T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/memory_handler.py:211
- Finding
- Cross-Session Disclosure of Stored Agent Memory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/memory_handler.py:211-220` **Vulnerability Type**: Missing session-level authorization and query scoping **Risk Level**: High ### Vulnerable Code ```python # If session_key provided, get that session if session_key: # Get recent exchanges from this session exchanges = mem.search_exchanges('', days=1, limit=20) # Filter to this session (will need session_id lookup) result['recent_exchanges'] = exchanges else: # Get recent exchanges across all sessions exchanges = mem.search_exchanges('', days=1, limit=10) result['recent_exchanges'] = exchanges ``` ### Technical Analysis The handler accepts a `session_key`, but it never uses that value as a database query constraint. The comment explicitly acknowledges that session filtering is still required. Instead, `search_exchanges()` retrieves recent exchanges across the accessible database. This violates tenant and session isolation in the documented multi-agent deployment model. Because raw exchanges may contain user messages, assistant reasoning, complete tool parameters, tool results, and user or channel metadata, an unscoped query can expose significantly more than ordinary memory summaries. The defect is an authorization failure rather than merely a relevance bug: possession of one valid session key does not limit the caller to that session's data. ### Attack Path 1. Multiple agents, users, or channels store exchanges in the shared PostgreSQL database. 2. An agent invokes the post-compaction handler with its own session key. 3. The handler enters the `if session_key` branch but performs an unscoped search for recent exchanges. 4. Exchanges belonging to unrelated sessions are returned in `recent_exchanges`. 5. The unrelated data is injected into the requesting agent's restored context or exposed through the command's JSON output. 6. Any credentials, private content, internal reasoning, or tool output in those exchanges bec ...[truncated 620 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Resolve the supplied `session_key` to an authorized database `session_id` and include it directly in the SQL query. 2. Scope every read by all applicable ownership attributes, such as `session_id`, `agent_id`, `instance_id`, provider, and channel. 3. Do not fetch globally and filter in application memory; enforce isolation in PostgreSQL. 4. Verify that the caller is authorized to access the requested session before returning any data. 5. Consider PostgreSQL Row-Level Security for shared deployments so accidental unscoped queries cannot cross tenant boundaries. 6. Return an error when a requested session does not exist or is not owned by the caller. 7. Add tests with multiple agents and sessions to prove that each caller can retrieve only its own exchanges. 8. Minimize returned fields and exclude assistant reasoning and complete tool payloads unless explicitly required. ]]>
