TL;DR

Before 0.2.121, the Claude Agent SDK for Python built the Claude Code command line as ["--resume", value], and the CLI declares --resume with an optional value, so a session id beginning with - was parsed as its own flag. The vendor advisory says a caller who controls that value can inject --mcp-config naming a stdio MCP server, which the CLI starts at launch, running an arbitrary command outside the SDK's permission controls (GHSA-h4mw-j7qp-8mwm, CVE-2026-96620, CVSS 4.0 9.2, GitHub CNA). Exploitation requires the application to pass untrusted input as the session id to resume. The fix, PR #1123, merged 2026-07-16 and shipped as 0.2.121 on PyPI on 2026-07-17 under a "Bug Fixes" heading; the advisory followed on 2026-09-12 and the CVE record on 2026-10-16. Current release is 0.2.168 (2026-10-15). If your app resumes sessions by an id that a user, a URL or another service supplies, upgrade and treat the value as untrusted even on the fixed line.

What happened

The SDK spawns the Claude Code CLI as a subprocess and translates ClaudeAgentOptions into argv. Its resume and session_id options went in as two tokens, flag then value. Because the CLI's -r, --resume [value] takes an optional value, a value such as --version was not bound to --resume and ran as a flag of its own; the PR body gives that example and notes that a value-taking flag "could escalate this further." The vendor advisory, published 2026-09-12 on the anthropics/claude-agent-sdk-python tab by OctavianGuzu, names the escalation: --mcp-config defining a stdio MCP server, "resulting in arbitrary command execution at CLI startup that bypassed the SDK's permission controls." The CVE record (GitHub CNA, published 2026-10-16) carries the same text, CWE-20, CWE-78 and CWE-88, and the vector CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N.

The two primaries describe the impact differently. PR #1123 (opened 2026-07-15 by qing-ant, merged 2026-07-16 as commit 347a1cb) says "because no shell is involved, this is argv-level flag injection, not arbitrary command execution." The advisory, written eight weeks later, says arbitrary command execution through the MCP configuration path. Both are the vendor's words; the advisory is the later and more complete assessment, and the MCP route needs no shell. This file uses the advisory's impact and records the PR's narrower sentence as the fix author's view at the time.

The fix is one shape change: each option is emitted as a single --resume=<value> token, so the value is always bound to its flag, and the CLI then rejects a dash-led value as an invalid session id. The SDK adds no validation of its own on POSIX. A follow-up, PR #1127 (merged 2026-07-20, same author, credited to HackerOne report #3870101 in the PR body), covers Windows: the SDK now refuses to spawn npm's claude.cmd batch shim, because cmd.exe re-parses the whole command line (the BatBadBut class, CVE-2024-27980), rejects & | < > ^ % ! " and line breaks in resume and session_id on Windows, prefers a native claude.exe, and binds dash-led extra_args values the same way. Windows users who relied on the npm shim get a hard connection error from the release that carries PR #1127 onward and need the native installer; the PR does not name that release, and this file does not guess it.

Three dates to hold apart. The fix shipped 2026-07-17 (PyPI 0.2.121; 0.2.120 was 2026-07-15) with release notes that say "Fixed argv flag injection via resume and session_id options" under Bug Fixes, with no severity and no advisory. The vendor advisory came 57 days later, on 2026-09-12. The CVE record and the GitHub Advisory Database row came on 2026-10-16, which is where this sweep found it, in the mcp, agent, claude and reviewed-critical pip listings at once. A reader who tracks the SDK through Dependabot or the database learned in October of a bug fixed in July; a reader who pinned 0.2.120 or earlier for stability has been exposed the whole time.

This is the SDK's second CVE batch this year. In April the SDK and the CLI shared OS command injections through environment-derived values: CVE-2026-35020 and CVE-2026-35021 are tracked in the Claude Code and Desktop batch file; a third record, CVE-2026-35022, appears in the advisory database's claude-agent-sdk listing (2026-04-06, unreviewed) with the same title and was not opened this run. The April bugs were shell interpolation; this one is argv binding with no shell. The class is the same one the corpus has for coding agents' allow rules (Continue CLI, the Claude Code find bypass): a value the application thought was data reached a parser that treats it as an instruction. The TypeScript Agent SDK's advisory tab lists nothing (checked 2026-10-17), and neither primary says whether it builds its argv the same way; that is unknown, not clear.

Severity here is high against the vendor's 9.2. The attack requirement is real: the application must forward a caller-controlled session id into resume. That is a common design for a web app or bot that lets a user continue a conversation by id, and in that design the result is command execution on the host running the agent with the agent's credentials, so the vendor's critical rating is defensible for those apps. Apps that mint session ids server-side and never accept one from a request were not reachable. Status patched on the vendor's fixed version, which has been on PyPI since July.

Am I affected?

pip show claude-agent-sdk 2>/dev/null | grep -i '^version'    # < 0.2.121 is affected; 0.2.168 is current (2026-10-15)
# Where does the session id come from? Any hit fed from a request, URL, message or database row is the exploitable shape.
grep -rn 'resume=\|session_id=' --include='*.py' . | grep -v 'site-packages'
# Lockfiles and requirement pins that hold the SDK back
grep -rn 'claude-agent-sdk' requirements*.txt pyproject.toml poetry.lock uv.lock 2>/dev/null

Affected if the installed SDK is below 0.2.121 and the application passes a value it did not generate into resume or session_id. On Windows, also affected through the claude.cmd shim path until the release carrying PR #1127 (merged 2026-07-20) if any option carried cmd.exe metacharacters. Not affected if the SDK is 0.2.121 or later on POSIX, or if every session id is minted by your own code and validated as a UUID before use.

If you are affected

Upgrade to the current claude-agent-sdk and remove any pin below 0.2.121. Validate session ids against the UUID shape before passing them to resume, on every version; the fix binds the value to its flag, it does not make the value trustworthy. If a pre-0.2.121 deployment accepted session ids from users, review the host the agent ran on for MCP server processes it did not configure and for the credentials the agent held, and rotate those per rotating-cloud-credentials.md; the agent-host checklist is in if-your-local-ai-agent-was-exploited.md. On Windows, install the native claude.exe rather than the npm shim.

Prevention

  • Run the agent subprocess in a sandbox that holds only the project and the credentials the task needs (agent-sandboxing.md); --mcp-config at launch is one of several ways a flag becomes a process.
  • Treat MCP server configuration as code: pin which servers the CLI may start and watch for ones you did not add (mcp-hygiene.md).
  • Do not pin AI SDKs to old versions; this fix was in a "Bug Fixes" line for eight weeks before any advisory named it (credential-hygiene.md covers the rotation that follows a missed fix).

Sources