GHSA-fh3r-g96v-f578: High severity npm/@arikusi/deepseek-mcp-server vulnerability
Cross-Session Data Exposure via Caller-Controlled sessionid
Project / Repository: arikusi/deepseek-mcp-server Affected version / commit tested: 1.6.0 / 04f28be2c6e99d3d4e443a6ae37cc35f0a71554a Vulnerability type: Authorization bypass / cross-session data exposure Authentication required: No
Summary The process-global SessionStore accepts caller-supplied sessionid values without binding them to any authenticated principal or transport session. An attacker can enumerate active session IDs via deepseeksessions, then reuse a victim-controlled sessionid in deepseekchat to retrieve and continue the victim's conversation context.
Affected Code - src/session.ts:42 - caller-controlled session IDs are looked up directly from the global in-memory map. - src/session.ts:67 - a new session is stored under the caller-controlled ID without ownership binding. - src/session.ts:109 - getMessages() retrieves messages for any supplied session ID. - src/tools/deepseek-chat.ts:195 - deepseekchat creates or reuses the supplied sessionid. - src/tools/deepseek-chat.ts:197 - previous messages are loaded from the supplied sessionid. - src/tools/deepseek-chat.ts:198 - previous messages are prepended into the attacker-controlled request. - src/tools/deepseek-chat.ts:243 - attacker-provided user messages are appended into the reused session. - src/tools/deepseek-chat.ts:245 - assistant responses are appended back into the reused session. - src/tools/deepseek-sessions.ts:37 - deepseeksessions list enumerates all active sessions. - src/tools/deepseek-sessions.ts:53 - each enumerated session ID is rendered back to the caller.
PoC Overview 1. Create a victim conversation with sessionid = "victim-session". 2. Call deepseeksessions with action = "list" and observe that victim-session is disclosed. 3. Call deepseekchat again with sessionid = "victim-session" from a separate attacker flow. 4. The upstream request now includes the victim's prior messages before the attacker's message.
Validation Environment Local 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.
Impact Any 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.
Remediation - Bind stored sessions to an authenticated transport session or other server-generated opaque identifier. - Do not allow arbitrary user-supplied sessionid values to select existing server-side state. - Remove or restrict deepseeksessions list so it does not disclose unrelated session IDs. - Reject reuse of a session unless the caller proves ownership of that session.
Attached Evidence 01deepseek-mcp-servercrosssessiondataexposure.txt
---
Patches (maintainer)
Fixed 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 deepseekchat and deepseeksessions tool handlers, so a sessionid 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.
Affected versions >=1.4.2, <1.7.0 are deprecated on npm. Upgrade to 1.7.0 or later.
Workaround
If upgrading is not immediately possible, run in STDIO transport (unset TRANSPORT=http) or stop the HTTP server.
Credit
Reported 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.
Note on severity
A 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.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
npm/@arikusi/deepseek-mcp-serverto a version that resolves this vulnerability.Fixed in 1.7.0 - Upgrade
Upgrade
arikusi/deepseek-mcp-serverto a version that resolves this vulnerability.Fixed in 1.7.0 - Configuration
If upgrading to 1.7.0+ is not immediately possible, run using STDIO transport by unsetting `TRANSPORT=http` (or otherwise configure to use STDIO) so the affected HTTP session transport path is not used.
HTTP transport TRANSPORT = (unset) - Configuration
Ensure the HTTP transport `SessionStore` is not process-wide; use a per-MCP-HTTP-session store injected into the `deepseek_chat` and `deepseek_sessions` tool handlers so a `session_id` from one HTTP session cannot read/enumerate/clear another session's state.
HTTP server / session isolation SessionStore scope = per MCP HTTP session - Compensating control
If applicable, stop the HTTP server as a temporary mitigation when upgrade is not possible, since STDIO transport was never affected (one process per client).
Event History
Frequently Asked Questions
What does an attacker need to exploit this issue?
No authentication is required. An attacker can use deepseek_sessions to enumerate active session IDs and then supply a victim's session_id to deepseek_chat.
What access can an attacker gain through a reused session ID?
The attacker can retrieve the victim session's prior conversation context and continue that conversation. The reported impact includes high confidentiality impact and low integrity and availability impact.
Which deployments are known to be affected?
Version 1.6.0, tested at commit 04f28be2c6e99d3d4e443a6ae37cc35f0a71554a, is identified as affected. The provided data does not establish a complete affected-version range.
How can I determine whether my code has the vulnerable behavior?
Check whether SessionStore uses a process-global in-memory map keyed by caller-supplied session_id values without binding them to an authenticated principal or transport session. Also check whether deepseek_chat loads prior messages for an arbitrary supplied session_id and whether deepseek_sessions exposes active IDs.