You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Resume replays envelopes from every session, leaking cross-session data #44
src/Internal/Runtime/LifecycleHandler.php:118 handles a Resume envelope by calling EventLog::replayAfter($after) and forwarding every yielded envelope onto the requesting session's transport. The underlying query at src/Store/EventLog.php:151 is SELECT payload_json FROM events WHERE rowid > :rowid ORDER BY rowid ASC and is not constrained by session_id, principal, or any other ownership column. When $msg->afterMessageId is null or an empty string the loop replays the entire append-only event log from the beginning, including envelopes that were recorded for other sessions.
A peer can therefore send Resume(after_message_id: "") and harvest every event ever logged across all sessions — tool inputs, telemetry, human prompts, granted leases, error payloads — even when those events belong to a different principal. The runtime advertises Resume as a session-scoped reconnection primitive in docs/guides/resume.md:29, and the auth invariant statement there explicitly promises "Only resume sessions under the same authenticated principal." The current code does not enforce that invariant. The events table already carries a session_id column and an events_session_idx index, so filtering by the requesting session is cheap.
Fix prompt: Scope the resume replay to envelopes the requesting session is entitled to see. In LifecycleHandler::handleResume, pass the calling Session's id and principal to a new EventLog::replayAfterForSession() (or add a session filter parameter to replayAfter()) and emit DATA_LOSS / PERMISSION_DENIED for cross-session after_message_id values. Add an integration test in tests/Integration/ResumeTest.php that opens two sessions, records events on each, and asserts that a Resume(after_message_id: "") on session A receives only envelopes from session A.
Activity
fix: address 17 open issues across auth, isolation, idempotency, and …
nficano commentedon May 25, 2026
Fixed in #52 (commit 03afbaa).