{"vulnerability": "cve-2025-66479", "sightings": [{"uuid": "9fbe9931-7fe6-4162-b9a9-1a713630f6b2", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2025-66479", "type": "seen", "source": "https://gist.github.com/yurukusa/a40f9255aec358aba5aa1cb6087d1903", "content": "Claude Code sandbox bypass disclosure (Aonan Guan, 2026-05-20): structural read through the claim-verify framework. ~2,000 words. Operator-side defenses for vendor-side claim-verify gap. Three independent operator-side checks plus the prompt-injection compound that turns the bypass into actual exfiltration.\n\n# Claude Code's Sandbox Was Bypassable for Five and a Half Months. Here's the Structural Read.\n\n**Disclosure context:** On 2026-05-20, security researcher Aonan Guan published [Second Time, Same Sandbox](https://oddguan.com/blog/second-time-same-sandbox-anthropic-claude-code-network-allowlist-bypass-data-exfiltration/). Every Claude Code release from sandbox GA (`v2.0.24`, 2025-10-20) through `v2.1.89` (2026-03-31) was vulnerable to at least one of two independent network-sandbox bypass paths. About 5.5 months. ~130 published versions. Both findings were silently fixed (`v2.0.55` and `v2.1.90`) with no Claude Code security advisory, no changelog flag, no notice to users on the ~130 vulnerable releases.\n\nThis post reads the disclosure through the structural framework operators have been organizing this kind of failure with for the past six weeks, and lists the three independent operator-side checks that would have caught the failure mode regardless of which specific bypass path was live.\n\n**Author's disclosure:** I publish the [Claude Code Claim-Verify Handbook](https://yurukusa.gumroad.com/l/claim-verify-handbook) (ships 2026-05-22). This Gist is a free public-asset analysis of Aonan Guan's disclosure, not a sales page. The book references this disclosure as a vendor-side current evidence axis in its industry recognition section. Free preview (the foreword, the three-stage framework, two representative case chapters, the full table of contents) is at .\n\n## The Two Bypass Paths\n\n**Finding 1 (CVE-2025-66479, recap).** A user who wrote `allowedDomains: []` in `settings.json` \u2014 the most restrictive setting the API offered, documented to mean \"block all outbound traffic\" \u2014 got the most permissive behavior. The check was `allowedDomains.length &gt; 0`. An empty array evaluated to false and silently disabled the proxy. The user said \"allow nothing.\" The implementation heard \"allow everything.\" Silently patched in `v2.0.55` (2025-11-26). The CVE was issued against `sandbox-runtime` on 2025-12-02; Claude Code itself got no CVE, no advisory, no changelog flag, no notice to users.\n\n**Finding 2 (the new one).** A SOCKS5 hostname null-byte injection. The user's policy says allow only `*.google.com`. An attacker who runs code inside the sandbox sends a hostname like `attacker-host.com\\x00.google.com`. The filter sees the trailing `.google.com` and approves; the operating system's `getaddrinfo` resolver truncates the C string at the null byte and dials `attacker-host.com`. The policy approved one host; the resolver dialed another. Silently patched in `v2.1.90` (2026-04-01). No security advisory.\n\nThe compound attack: combine either bypass with a prompt-injection vector (a hidden instruction in a GitHub issue comment that Claude Code reads), and anything inside the sandbox can be sent to any server on the internet. Credentials, source code, environment variables, internal customer data. Even when the user explicitly restricted egress to a strict wildcard allowlist.\n\n## The Three-Stage Framework, Applied to the Vendor Side\n\nOperators reading the `anthropics/claude-code` issue tracker over the past six weeks have been organizing claim-vs-reality failures with a three-stage structural framework:\n\n- **Stage 1 \u2014 Operator intent.** The operator writes something explicit (`settings.json`, `CLAUDE.md`, `/config`, a subagent's frontmatter, a `memory:` directive) describing the constraint they expect the system to enforce.\n- **Stage 2 \u2014 System status claim.** The system reports a status that confirms the constraint is in effect. `/context` says auto-compact is off; the sandbox documentation says `allowedDomains: [\"*.google.com\"]` blocks everything else; the changelog says \"Releasing a sandbox mode for the BashTool.\"\n- **Stage 3 \u2014 Runtime action.** The actual runtime behavior diverges from what the system claimed in Stage 2. The auto-compact fires anyway; the sandbox dials `attacker-host.com`; the deny rule is silently bypassed for a subagent that has no explicit tool binding.\n\nAonan Guan's disclosure is a perfect-fit vendor-side instance of this framework:\n\n- **Stage 1 \u2014 Operator intent.** The operator wrote `allowedDomains: [\"*.google.com\"]` in `settings.json`. The operator's intent: only `.google.com` egress is allowed.\n- **Stage 2 \u2014 System status claim.** The sandbox's documented contract: SOCKS5-mediated egress filtering. The sandbox went GA on 2025-10-20 with the changelog announcement \"Releasing a sandbox mode for the BashTool on Linux &amp; Mac.\" The implication: this thing enforces.\n- **Stage 3 \u2014 Runtime action.** For 5.5 months, the proxy that mediates the egress decision had two independent bypasses live in production. The operator's intent in Stage 1 and the system's claim in Stage 2 both said the constraint was enforced. The runtime action in Stage 3 said otherwise. The divergence ran for ~130 versions before either path was silently patched, and the operator was never notified.\n\nThe same framework that organizes 130 operator-side cases in the `anthropics/claude-code` issue tracker reads the vendor-side sandbox disclosure cleanly. The structural property is symmetric across the operator/vendor boundary: an explicit constraint is written, a status claim says it's in effect, the runtime diverges, and the divergence is only discovered when an outside party tests it.\n\n## Why This Is Not Just a Bug Report\n\nTwo characteristics distinguish this disclosure from a routine vulnerability:\n\n**Symmetry across the operator-vendor boundary.** The same failure mode that operators have been reporting in the issue tracker \u2014 `permissions.deny` silently bypassed, `autocompact: false` ignored, `memory:` directives unreferenced, subagent tool restrictions not inherited \u2014 also occurs at the vendor level when the vendor writes the sandbox contract. The failure mode is not a function of who wrote the constraint. It is a function of whether the contract and the runtime are independently verified.\n\n**Silent fix is itself the structural property.** Both findings were patched without a Claude Code security advisory. No CVE was issued by Anthropic for either. No notice was sent to users on the ~130 vulnerable releases. A team running `allowedDomains: [...]` in production from October 20 through November 26 had no way to know the sandbox was effectively off, and no notice afterwards that it had ever been off. The same \"silent fix\" pattern shows up repeatedly in the operator-side issue tracker: a Claude Code release fixes a deny-rule regression, an auto-compact regression, a memory-directive regression, with the changelog describing it as a feature improvement rather than a security-relevant correction. The operator never gets the signal that re-verification is needed.\n\nThe structural read: the constraint-enforcement contract is treated as a quality-of-life feature on both sides, not as a security boundary that requires re-verification on every version bump.\n\n## Three Operator-Side Checks That Catch This Pattern\n\nRegardless of which specific bypass path is live in any given release, three operator-side checks will catch the structural property \u2014 that the sandbox's claimed enforcement diverges from its runtime enforcement \u2014 within seconds of a new Claude Code version landing on the workstation.\n\n**Check 1: Verify the sandbox out-of-band.** Do not trust the sandbox's claim that egress is restricted. Verify it by trying to reach a blocked host from inside the sandbox and confirming the connection actually fails. The smallest possible test:\n\n```bash\n# Inside a Claude Code session with sandbox enabled and a strict allowlist:\ncurl -m 5 -sSf https://example.com &gt;/dev/null \\\n  &amp;&amp; echo \"FAIL: sandbox approved a host the policy should have blocked\" \\\n  || echo \"OK: sandbox blocked\"\n```\n\nRun this on every Claude Code version bump. If `example.com` (or any host outside the allowlist) is reachable, the sandbox is not enforcing what the documentation claims it enforces. This is the only way to catch a Finding-1-style \"allow nothing was read as allow everything\" or a Finding-2-style \"null-byte injection bypasses the wildcard check.\" Both bypasses would fail this test the moment a vulnerable version was installed.\n\n**Check 2: Pin sandbox enforcement at the OS level, not at the JavaScript proxy level.** The OS-level enforcement (`sandbox-exec` on macOS, `bubblewrap` on Linux) correctly pins the agent to localhost in both bypass scenarios. The SOCKS5 proxy that the sandbox delegates egress decisions to runs on the host with full network privileges. Fool the proxy, and the host dials. Run Claude Code under an OS-level sandbox that the JavaScript-layer proxy cannot influence:\n\n```bash\n# macOS: wrap Claude Code in sandbox-exec with a deny-internet profile\nsandbox-exec -f deny-internet.sb claude code\n# Linux: wrap in bubblewrap with --share-net 0\nbwrap --share-net 0 --bind / / claude code\n```\n\nA JavaScript proxy that misinterprets a null byte in a hostname cannot cause the OS to dial a blocked host if the OS itself has no internet route. The OS-level boundary is independent of whatever the JavaScript proxy thinks it is enforcing.\n\n**Check 3: Audit `cli.js` on every version bump for sandbox-related code changes.** Aonan Guan found both bugs by reverse-engineering the bundled `cli.js`. Operators running Claude Code in environments where vendor silence around sandbox patches is unacceptable can do the same. A minimal audit pattern:\n\n```bash\n# Capture the sandbox-related code surface on each version bump:\nwhich claude | xargs -I{} dirname {} | xargs -I{} find {} -name \"cli.js\" \\\n  -exec grep -n \"socks\\|allowedDomains\\|sandbox\\|proxy\" {} \\;\n```\n\nThe audit is not a security review; it is a heuristic for \"did the sandbox-related code surface change since the previous version?\" A diff that touches `socks` parsing or `allowedDomains` evaluation is a signal to re-run Check 1 explicitly and to look at the related issues on the tracker.\n\n## The Compound With Prompt Injection\n\nA bypass alone is just a misconfigured proxy. The bypass becomes an exfiltration vector when combined with prompt injection: a hidden instruction in a GitHub issue comment that Claude Code reads, a CLAUDE.md file in an open-source dependency, a comment in a code review the agent processes. The hidden instruction asks the model to send local credentials to `attacker-host.com\\x00.google.com`. The model emits the command. The sandbox approves it. The host dials the attacker's server. Credentials, source code, environment variables, internal data \u2014 everything inside the sandbox \u2014 flows out through a hostname the user's policy explicitly allowed.\n\nOperator-side mitigations for the prompt-injection compound:\n\n- **Disable agent reading of untrusted content.** If your agent reads issue comments, code review threads, or third-party CLAUDE.md files, treat those inputs as untrusted. Either parse them through a stripping step that removes anything resembling an instruction, or run the agent in a sandbox that has no egress at all (Check 2 above).\n- **Egress allowlists at the OS level, not the application level.** As above. The OS-level allowlist is unaffected by a JavaScript proxy that misinterprets a hostname.\n- **Per-tool secret scoping.** Do not give the agent ambient access to credentials that an exfiltration vector could send out. Scope each secret to the tool that needs it, expose it only at the moment of the tool's invocation, revoke after.\n\n## Where This Fits in the Broader Pattern\n\nThe disclosure is the strongest vendor-side current evidence of a pattern the operator community has been documenting in the `anthropics/claude-code` issue tracker for the past six weeks. The recurring shape: an explicit constraint is written by the operator (or by the vendor in this case); the system reports the constraint is in effect; the runtime diverges; the operator has no signal that re-verification is needed.\n\nA non-exhaustive list of the structural cluster on the operator side: `permissions.deny` regressions silently introduced by version bumps (Issue #57491, #57486 \u2014 the same v2.1.128 that silently changed Allow rule interpretation while the changelog described it as a feature improvement); `autocompact: false` ignored mid-session with `/context` continuing to claim it was off (Issue #57490); subagent tool restrictions not inherited from parent `settings.json` deny rules (Issue #57068); auth state and tool liveness claims diverging from actual state (Issue #57285). The Claim-Verify Handbook ships 2026-05-22 with 130 cases (15 main + 115 appendix D) organized through the three-stage framework, with 14 operator-side defenses against the pattern.\n\nThe vendor-side data point Aonan Guan published is qualitatively distinct: it shows that the same structural failure mode operates at the layer where the vendor writes the contract, with the same characteristic silent fix and missing-advisory tail. The pattern is not \"agents misbehave\" \u2014 it is \"explicit constraints and runtime behavior diverge without a verification mechanism, on both sides of the contract.\"\n\n## Read Before Buy\n\nThe Claim-Verify Handbook's foreword, three-stage framework, industry recognition signal (now twelve independent verification axes including this disclosure), and two full representative case chapters are in the free preview Gist: . Read the framework first. If the structural read above resonates with what you are seeing in your own Claude Code operation, the full handbook organizes 130 cases of the operator-side pattern with mitigations.\n\n**Free user-side prevention work the book references**: the `cc-safe-setup` hook collection (MIT, 750+ hooks, 30K+ installs at `github.com/yurukusa/cc-safe-setup`) ships the hook pattern Check 1 above generalizes \u2014 a per-version verification step that runs at session start and confirms the sandbox is actually enforcing what its configuration says it enforces. Three of the five Chapter 9 detection tools (`claim-vs-caveat-checker`, `subagent-inheritance-tester`, `settings-regression-tester`) are in feature branches awaiting merge to main; the fourth (`auth-path-detector`) and the fifth (`context-diff-monitor` as a design sketch) are referenced in the book.\n\nIf the only useful thing you take from this Gist is Check 1 above \u2014 verify the sandbox out-of-band, on every version bump \u2014 that is enough.\n", "creation_timestamp": "2026-05-21T07:18:12.000000Z"}, {"uuid": "f77402d1-3958-461e-acf3-40747f4ade6c", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2025-66479", "type": "seen", "source": "https://bsky.app/profile/mel-echosphere.bsky.social/post/3mmlvd4ifra2g", "content": "\u5916\u304b\u3089\u898b\u305f\u7814\u7a76\u8005\u304c2\u56de\u8997\u3044\u3066\u30012\u56de\u3068\u3082\u5b8c\u5168\u30d0\u30a4\u30d1\u30b9\u3060\u3063\u305f\u3002\n\n1\u4ef6\u76ee\uff08CVE-2025-66479\uff09\uff1aallowedDomains \u3092\u7a7a\u306b\u3057\u305f\u3089\u300c\u5168\u90e8\u30d6\u30ed\u30c3\u30af\u300d\u3058\u3083\u306a\u304f\u300c\u5168\u90e8\u8a31\u53ef\u300d\u3068\u3057\u3066\u52d5\u3044\u305f\u3002\n2\u4ef6\u76ee\uff1aSOCKS5 \u306b null byte \u3092\u631f\u3093\u3067 allowlist \u3092\u7d20\u901a\u308a\u3002\n\n1\u4ef6\u76ee\u3092\u76f4\u3057\u305f\u30ea\u30ea\u30fc\u30b9\u304c2\u4ef6\u76ee\u3092\u305d\u306e\u307e\u307e\u51fa\u8377\u3057\u3066\u308b\u3002\u5b89\u5168\u3060\u3063\u305f\u77ac\u9593\u306f\u30bc\u30ed\u3002\ud83d\udc8e\n\nhttps://oddguan.com/blog/second-time-same-sandbox-anthropic-claude-code-network-allowlist-bypass-data-exfiltration/", "creation_timestamp": "2026-05-24T11:47:05.516579Z"}]}