CVE-2026-96620: an untrusted session ID could inject flags into Claude Code through Anthropic's Python Agent SDK
Summary
Anthropic's Claude Agent SDK for Python, the library developers use to build their own agents on top of Claude Code, passed the resume option to the Claude Code CLI as a separate argument without checking it. The CLI's --resume flag takes an optional value, so a value starting with a dash was read as a new flag instead of a session ID. Anthropic's advisory says an attacker who controls that value could inject --mcp-config to define a stdio MCP server, which runs a command of their choosing when the CLI starts, outside the SDK's permission controls. It only matters for apps that pass untrusted input as the session ID to resume, such as a 'resume my session' endpoint. Version 0.2.121, released in July, fixes it. Anthropic's advisory is dated Sep 12, 2026, and the CVE reached NVD on Oct 16.
Severity
Timeline
Anthropic merges pull request #1123, which passes --resume and --session-id to the CLI as single --flag=value tokens.
claude-agent-sdk 0.2.121 is released on GitHub and PyPI with the fix.
0.2.124 follows with Windows hardening (pull request #1127): the SDK refuses to spawn npm's claude.cmd shim and rejects cmd.exe metacharacters in resume and session_id on Windows.
Anthropic publishes advisory GHSA-h4mw-j7qp-8mwm (Critical, CVSS 4.0 9.2) for versions before 0.2.121, crediting HackerOne user moamenmahmood.
The advisory is added to the GitHub Advisory Database, and NVD publishes CVE-2026-96620.
How it happened
The SDK starts the Claude Code CLI as a subprocess and builds its argument list from the options a developer passes in. Before 0.2.121 it added resume as two tokens, --resume and then the value, and did the same for session_id. The CLI declares --resume with an optional value (a bare claude --resume opens a session picker), and its parser won't take a dash-leading next token as that value, so the token became a flag of its own. Anthropic's pull request shows a value of --version making the CLI print its version and return nothing. The advisory describes the worst case: an injected --mcp-config that defines a stdio MCP server, whose command runs when the CLI starts, without going through the SDK's permission controls. No shell is involved here. The problem is that a value turned into a flag. The fix sends the option as one token, --resume=<value>, so the CLI treats a dash-leading value as an invalid session ID and refuses it. In 0.2.124 Anthropic also closed a Windows path where the SDK could launch npm's claude.cmd shim, which cmd.exe re-parses, so cmd.exe metacharacters in argument values could slip through. The TypeScript SDK's changelog lists similar equals-form hardening in 0.3.208 and 0.3.212, but Anthropic's advisory covers only the Python package. Advisory GHSA-h4mw-j7qp-8mwm lists CWE-20, CWE-78 and CWE-88.
How to check your app
- Run pip show claude-agent-sdk, or check your lockfile, and make sure you're on 0.2.121 or later.
- On Windows, use 0.2.124 or later. Its release notes say to use the native installer, an explicit claude.exe path or a wheel that bundles the CLI instead of npm's claude.cmd shim.
- Search your code for the resume and session_id options in ClaudeAgentOptions. If either can come from a request, URL, chat message or anything else a user controls, check it against session IDs your app created for that user before passing it on.
- If an older version ran with untrusted resume input, review the MCP servers and processes the Claude CLI started on that host, and rotate credentials the agent process could read.
Sources
- Anthropic advisory GHSA-h4mw-j7qp-8mwm (CVE-2026-96620)
- GitHub Advisory Database: GHSA-h4mw-j7qp-8mwm
- NVD: CVE-2026-96620
- Pull request #1123: Pass --resume and --session-id as a single argv token
- claude-agent-sdk v0.2.121 release
- Pull request #1127: Refuse to spawn .bat/.cmd CLI scripts on Windows
- claude-agent-sdk v0.2.124 release