{"id":"GHSA-fh3r-g96v-f578","revision":"32aad0e771914d11be4f72cfb2af1a86","records":[{"revision":"32aad0e771914d11be4f72cfb2af1a86","observedAt":"2026-10-24T13:17:17.793+00:00","statement":{"source":"osv","id":"GHSA-fh3r-g96v-f578","aliases":["CVE-2026-55604"],"title":"@arikusi/deepseek-mcp-server has an Authorization Bypass Through User-Controlled Key","description":"# Cross-Session Data Exposure via Caller-Controlled `session_id`\n\nProject / Repository: `arikusi/deepseek-mcp-server`  \nAffected version / commit tested: `1.6.0` / `04f28be2c6e99d3d4e443a6ae37cc35f0a71554a`  \nVulnerability type: Authorization bypass / cross-session data exposure \nAuthentication required: No\n\n## Summary\nThe process-global `SessionStore` accepts caller-supplied `session_id` values without binding them to any authenticated principal or transport session. An attacker can enumerate active session IDs via `deepseek_sessions`, then reuse a victim-controlled `session_id` in `deepseek_chat` to retrieve and continue the victim's conversation context.\n\n## Affected Code\n- `src/session.ts:42` - caller-controlled session IDs are looked up directly from the global in-memory map.\n- `src/session.ts:67` - a new session is stored under the caller-controlled ID without ownership binding.\n- `src/session.ts:109` - `getMessages()` retrieves messages for any supplied session ID.\n- `src/tools/deepseek-chat.ts:195` - `deepseek_chat` creates or reuses the supplied `session_id`.\n- `src/tools/deepseek-chat.ts:197` - previous messages are loaded from the supplied `session_id`.\n- `src/tools/deepseek-chat.ts:198` - previous messages are prepended into the attacker-controlled request.\n- `src/tools/deepseek-chat.ts:243` - attacker-provided user messages are appended into the reused session.\n- `src/tools/deepseek-chat.ts:245` - assistant responses are appended back into the reused session.\n- `src/tools/deepseek-sessions.ts:37` - `deepseek_sessions list` enumerates all active sessions.\n- `src/tools/deepseek-sessions.ts:53` - each enumerated session ID is rendered back to the caller.\n\n## PoC Overview\n1. Create a victim conversation with `session_id = \"victim-session\"`.\n2. Call `deepseek_sessions` with `action = \"list\"` and observe that `victim-session` is disclosed.\n3. Call `deepseek_chat` again with `session_id = \"victim-session\"` from a separate attacker flow.\n4. The upstream request now includes the victim's prior messages before the attacker's message.\n\n## Validation Environment\nLocal runtime verification on Windows host with Node.js `v24.11.1`, using the repository code at the tested commit and a local mock DeepSeek client to capture the effective message list passed upstream.\n\n## Impact\nAny reachable caller can enumerate active session IDs and read prior conversation history stored in memory for other callers within the same server process. The same flaw also allows attacker-controlled continuation of another user's session state.\n\n## Remediation\n- Bind stored sessions to an authenticated transport session or other server-generated opaque identifier.\n- Do not allow arbitrary user-supplied `session_id` values to select existing server-side state.\n- Remove or restrict `deepseek_sessions list` so it does not disclose unrelated session IDs.\n- Reject reuse of a session unless the caller proves ownership of that session.\n\n## Attached Evidence\n[01_deepseek-mcp-server_cross_session_data_exposure.txt](https://github.com/user-attachments/files/26991248/01_deepseek-mcp-server_cross_session_data_exposure.txt)\n\n---\n\n## Patches (maintainer)\n\nFixed in **1.7.0**. The HTTP transport's `SessionStore` is no longer a process-wide singleton: each MCP HTTP session gets its own store, injected into the `deepseek_chat` and `deepseek_sessions` tool handlers, so a `session_id` from one HTTP session cannot read, enumerate, or clear another session's state. STDIO transport was never affected (one process per client). Integration tests in `src/transport-isolation.test.ts` assert the isolation.\n\nAffected versions `>=1.4.2, <1.7.0` are deprecated on npm. Upgrade to 1.7.0 or later.\n\n## Workaround\n\nIf upgrading is not immediately possible, run in STDIO transport (unset `TRANSPORT=http`) or stop the HTTP server.\n\n## Credit\n\nReported independently by @232-323 and @2REBCat (tested against 1.6.0). The same root cause was found and fixed concurrently by the maintainer during a security audit, shipped in 1.7.0. All parties are credited as finders.\n\n## Note on severity\n\nA connected client could read other clients' conversation history (C:H), inject messages into their sessions (I:L), and clear or delete other clients' sessions (A:L). Scope is unchanged: the impact stays within the application's own authorization boundary, which is a cross-tenant authorization bypass, so S:U is correct.","state":0,"publishedAt":"2026-08-25T18:37:27+00:00","modifiedAt":"2026-08-26T01:18:34.8648407+00:00","affected":[{"ecosystem":"npm","name":"@arikusi/deepseek-mcp-server","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"1.4.2"},{"kind":"fixed","version":"1.7.0"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"HIGH"}],"references":["https://github.com/arikusi/deepseek-mcp-server/security/advisories/GHSA-fh3r-g96v-f578","https://nvd.nist.gov/vuln/detail/CVE-2026-55604","https://github.com/arikusi/deepseek-mcp-server","https://github.com/arikusi/deepseek-mcp-server/releases/tag/v1.7.0"],"sourceUrl":"https://github.com/advisories/GHSA-fh3r-g96v-f578","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-fh3r-g96v-f578","identifiers":["GHSA-fh3r-g96v-f578","CVE-2026-55604"]},"retained":false,"historicalAffected":[]}],"coverage":[]}