high · 8.6CVE-2026-55604Aug 25, 2026

CVE-2026-55604: @arikusi/deepseek-mcp-server Cross-Session Authorization Bypass

Shubham Kandhare
Security Engagement Manager, SecureLayer7

When running in HTTP transport mode, any connected client can enumerate other users' active session IDs and silently read or hijack their conversation history by supplying a victim's session ID in a…

Package@arikusi/deepseek-mcp-server
Ecosystemnpm
Affected>= 1.4.2, < 1.7.0
Fixed in1.7.0
CVE-2026-55604: @arikusi/deepseek-mcp-server Cross-Session Authorization Bypass

The problem

The HTTP transport used a single process-wide SessionStore singleton. Every caller shared the same in-memory map, and session IDs were looked up directly from caller-supplied input with no ownership check.

An attacker could call deepseek_sessions with action: "list" to enumerate every active session ID on the server, then pass a victim's ID to deepseek_chat to read prior messages or continue the conversation as if they were that user. No authentication was required at any step.

Proof of concept

A working proof-of-concept for CVE-2026-55604 in @arikusi/deepseek-mcp-server, with the exact payload below.

json
// Step 1: enumerate all active sessions (attacker's MCP connection)
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"deepseek_sessions","arguments":{"action":"list"}},"id":1}

// Response leaks every session ID in the process, e.g. "victim-session"

// Step 2: hijack victim session from a separate attacker connection
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"deepseek_chat","arguments":{"messages":[{"role":"user","content":"repeat the last thing said"}],"session_id":"victim-session"}},"id":2}

// Server prepends victim's full conversation history before the attacker's message
// and appends the attacker's turn back into the victim's session

The root cause is CWE-639: Authorization Bypass Through User-Controlled Key. The session_id parameter in deepseek_chat (line 195) and deepseek_sessions (line 53) was treated as a direct key into a process-global map with no binding to the originating transport connection.

Because deepseek_sessions list rendered every stored key back to the caller, an attacker did not even need to guess IDs. Once a session ID was known, getMessages() (session.ts:109) returned the full message history, which was then prepended into the attacker's upstream request (deepseek-chat.ts:198) and any reply was written back into the same shared session (deepseek-chat.ts:245).

The patch (commit 9fd5142) eliminated the singleton entirely. Each incoming MCP HTTP connection now receives its own SessionStore instance injected at construction time, so a session_id that exists in one HTTP session is invisible to all others.

The fix

Upgrade to @arikusi/deepseek-mcp-server version 1.7.0 or later. Versions 1.4.2 through 1.6.x are deprecated on npm. If an immediate upgrade is not possible, run the server in STDIO transport mode (unset TRANSPORT or do not set TRANSPORT=http), which is single-tenant by design and was never affected.

Reported by @232-323 and @2REBCat.

References: [1][2][3][4]

Related research