Blog · Analysis
dsh2shell: unauthenticated RCE in web-exposed DeepSeek Harness
August 25, 2026 · dshbase · security analysis for installers
DeepSeek Harness is an agent runtime people routinely run as a web service for remote use. Security researcher ChaoMixian published a working unauthenticated RCE against exactly that deployment shape (PoC named dsh2shell, disclosed August 21, no CVE assigned yet) — rated CVSS 9.8 critical: network attack vector, low complexity, no privileges, no user interaction. A FOFA sweep found roughly 600+ instances exposed with the vulnerable pattern.
Root cause: trusting a header for an access decision
DSH's management RPC endpoints (session.create, provider.add, session.selectModel, permission.defaultPreset, and friends) are supposed to be local-only. The check is the problem: the server decides "is this localhost?" by reading the literal HTTP Host header — a value the client fully controls — instead of validating the real network source. Send Host: localhost and the privileged RPC treats you as a local caller.
The three-step chain
- Register a malicious provider. Point DSH at an attacker-controlled "Fake LLM" server (an OpenAI-compatible endpoint that returns scripted responses).
- Switch the session model. Select that fake provider as the active model — no auth needed at any point.
- Drive the built-in bash tool. The fake LLM's chat-completions reply contains a tool-call instruction, so the agent dutifully executes an arbitrary shell command and returns the output. From there: full host takeover.
No API key, no login, no user interaction — the entire chain runs over unauthenticated HTTP.
Why it hurts: keys everywhere
In the researcher's controlled tests, exposed environments commonly carried .env and .credentials.yaml files with live credentials: DeepSeek, Kimi (Moonshot), MiniMax, Qwen, OpenAI, GLM, Tavily, plus aggregator keys (StepFun / OpenRouter). Practical impact is quota theft at your expense and the instance as a pivot point for lateral movement. Agent runtimes read your files and run your shell — a compromised one is a compromised machine, full stop.
Fixes, in order of bluntness
- Stop exposing dsh on the public internet. Run it on loopback/VPN, or behind an authenticated reverse proxy. Agent web UIs do not belong on port 80 of a server with a public IP.
- Never trust the client Host header at the proxy. Force it: Nginx
proxy_set_header Hostto a fixed value, so even a spoofed request can't reach the loopback branch. - Authenticate the RPC surface. Token or basic auth in front of the management endpoints, even inside the boundary.
- Update. Track the official repository for the fix and apply it; meanwhile treat any exposed instance as compromised and rotate everything it could see.
The lesson for early-stage agent tooling
This vulnerability class — loopback checks implemented as header comparisons — is a classic 2010s mistake showing up in new software. The practical takeaways for anyone running developer-preview agent frameworks: a "localhost-only" flag is a convenience feature, not a security boundary; audit what a client can spoof before trusting any source check; and treat the host that runs your agent's bash tool like a production credential store, because that's exactly what it is. Preview software moves fast — security review is the one stage that shouldn't.