Skip to content

Commit e7a0c5f

Browse files
tulgaakekglaforge
authored andcommitted
fix: URL-encode userId and sessionId in VertexAiClient API URLs
User-supplied userId and sessionId values were concatenated directly into Vertex AI REST API URL paths and query parameters without encoding. This allows query parameter injection via userId (e.g., "attacker&extra_param=value") and path manipulation via sessionId (e.g., "../../other-resource"). Apply URLEncoder.encode() to all user-supplied values before URL construction in listSessions, listEvents, getSession, deleteSession, and appendEvent. Bug: CWE-116 (Improper Encoding or Escaping of Output)
1 parent 88eb0f5 commit e7a0c5f

1 file changed

Lines changed: 20 additions & 5 deletions

File tree

core/src/main/java/com/google/adk/sessions/VertexAiClient.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import io.reactivex.rxjava3.core.Single;
1515
import java.io.IOException;
1616
import java.io.UncheckedIOException;
17+
import java.net.URLEncoder;
18+
import java.nio.charset.StandardCharsets;
1719
import java.util.HashMap;
1820
import java.util.List;
1921
import java.util.Map;
@@ -103,40 +105,53 @@ private Completable pollOperation(String operationId, int attempt) {
103105
});
104106
}
105107

108+
private static String encodeParam(String value) {
109+
return URLEncoder.encode(value, StandardCharsets.UTF_8);
110+
}
111+
106112
Maybe<JsonNode> listSessions(String reasoningEngineId, String userId) {
107113
return performApiRequest(
108114
"GET",
109-
"reasoningEngines/" + reasoningEngineId + "/sessions?filter=user_id=" + userId,
115+
"reasoningEngines/" + reasoningEngineId
116+
+ "/sessions?filter=user_id=" + encodeParam(userId),
110117
"")
111118
.flatMapMaybe(VertexAiClient::getJsonResponse);
112119
}
113120

114121
Maybe<JsonNode> listEvents(String reasoningEngineId, String sessionId) {
115122
return performApiRequest(
116123
"GET",
117-
"reasoningEngines/" + reasoningEngineId + "/sessions/" + sessionId + "/events",
124+
"reasoningEngines/" + reasoningEngineId
125+
+ "/sessions/" + encodeParam(sessionId) + "/events",
118126
"")
119127
.doOnSuccess(apiResponse -> logger.debug("List events response {}", apiResponse))
120128
.flatMapMaybe(VertexAiClient::getJsonResponse);
121129
}
122130

123131
Maybe<JsonNode> getSession(String reasoningEngineId, String sessionId) {
124132
return performApiRequest(
125-
"GET", "reasoningEngines/" + reasoningEngineId + "/sessions/" + sessionId, "")
133+
"GET",
134+
"reasoningEngines/" + reasoningEngineId
135+
+ "/sessions/" + encodeParam(sessionId),
136+
"")
126137
.flatMapMaybe(apiResponse -> getJsonResponse(apiResponse));
127138
}
128139

129140
Completable deleteSession(String reasoningEngineId, String sessionId) {
130141
return performApiRequest(
131-
"DELETE", "reasoningEngines/" + reasoningEngineId + "/sessions/" + sessionId, "")
142+
"DELETE",
143+
"reasoningEngines/" + reasoningEngineId
144+
+ "/sessions/" + encodeParam(sessionId),
145+
"")
132146
.doOnSuccess(ApiResponse::close)
133147
.ignoreElement();
134148
}
135149

136150
Completable appendEvent(String reasoningEngineId, String sessionId, String eventJson) {
137151
return performApiRequest(
138152
"POST",
139-
"reasoningEngines/" + reasoningEngineId + "/sessions/" + sessionId + ":appendEvent",
153+
"reasoningEngines/" + reasoningEngineId
154+
+ "/sessions/" + encodeParam(sessionId) + ":appendEvent",
140155
eventJson)
141156
.flatMapCompletable(
142157
response -> {

0 commit comments

Comments
 (0)