Skip to content

Commit ad1ea25

Browse files
Merge pull request #1435 from prasanna8585:fix/listevents-ownership-check
PiperOrigin-RevId: 1004674904
2 parents 145901d + 6cb6557 commit ad1ea25

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

‎core/src/main/java/com/google/adk/sessions/VertexAiSessionService.java‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,26 @@ private ListSessionsResponse parseListSessionsResponse(
177177
@Override
178178
public Single<ListEventsResponse> listEvents(String appName, String userId, String sessionId) {
179179
validateSessionId(sessionId);
180-
return listEventsInternal(appName, sessionId, /* filter= */ null);
180+
String reasoningEngineId = parseReasoningEngineId(appName);
181+
return client
182+
.getSession(reasoningEngineId, sessionId)
183+
.flatMapSingle(
184+
getSessionResponseMap -> {
185+
// Enforce ownership using the owner reported by the backend, not the
186+
// requested user id, mirroring the check getSession/deleteSession use.
187+
// Deny as empty so existence is not revealed to a non-owner.
188+
String ownerUserId =
189+
Optional.ofNullable(getSessionResponseMap.get("userId"))
190+
.map(JsonNode::asText)
191+
.orElse(null);
192+
if (!userId.equals(ownerUserId)) {
193+
return Single.just(ListEventsResponse.builder().build());
194+
}
195+
return listEventsInternal(appName, sessionId, /* filter= */ null);
196+
})
197+
// No session found at all (rather than an ownership mismatch): behave the
198+
// same as before, returning an empty response instead of erroring.
199+
.defaultIfEmpty(ListEventsResponse.builder().build());
181200
}
182201

183202
private Single<ListEventsResponse> listEventsInternal(

‎core/src/test/java/com/google/adk/sessions/VertexAiSessionServiceTest.java‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,17 @@ public void getSession_wrongUser_returnsEmpty() {
571571
.isNull();
572572
}
573573

574+
@Test
575+
public void listEvents_wrongUser_returnsEmpty() {
576+
// Session "1" belongs to "user" and has an event in eventMap (MOCK_EVENT_STRING).
577+
// A different user must not be able to read those events - mirrors
578+
// getSession_wrongUser_returnsEmpty above, applied to listEvents.
579+
ListEventsResponse response =
580+
vertexAiSessionService.listEvents("123", "attacker", "1").blockingGet();
581+
582+
assertThat(response.events()).isEmpty();
583+
}
584+
574585
@Test
575586
public void deleteSession_wrongUser_deniedAndSessionKept() {
576587
sessionMap.put("victim-session", mockSessionJson("victim-session", "2024-12-12T12:12:12Z"));

0 commit comments

Comments
 (0)