← Back to Feed CACHED · 2026-06-30 15:26:54 · CACHE_KEY CVE-2026-46406
CVE-2026-46406 · CWE-59 · Disclosed 2026-06-29

Claude Code is an agentic coding tool

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A developer tool left its scratch paper in the shared printer tray, with the recipient's name written in pencil

CVE-2026-46406 affects Anthropic's @anthropic-ai/claude-code npm package, versions 2.1.59 through 2.1.127, patched in 2.1.128. The /copy slash command writes the model response to a hardcoded path (/tmp/claude/response.md) without per-UID isolation, randomness, or O_NOFOLLOW-style symlink protection. The directory is created 0755 and the file 0644, so any other local user on the same box can (a) read the privileged user's response — which often contains pasted secrets, source, or tokens — or (b) pre-stage a symlink at that path to redirect the write and clobber an attacker-chosen file owned by the victim. CWE-59 (link following) compounded by CWE-377 (insecure temp file) and CWE-200 (info disclosure).

There is no vendor CVSS from Anthropic in NVD, but GitLab's advisory tracker computed 6.1 Medium (AV:L/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:H). That math is fair. This is a local-only, user-interaction-required bug in an interactive developer CLI. It is not a remote code execution, not network-reachable, and the affected install base is developer workstations and CI runners — not domain controllers, hypervisors, or edge appliances. The vendor framing matches reality; we land at MEDIUM, slightly below 6.1 because in practice almost nobody runs Claude Code on a shared multi-user host.

"Local-only TOCTOU/symlink bug in a developer CLI — annoying, not a fleet-wide emergency. Patch through normal channels."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Attacker establishes a local unprivileged shell on the same host

The exploit requires the attacker to already have an interactive or scripted local account on the same Linux/macOS box that the victim runs Claude Code on. This is the foundational prerequisite — the bug is AV:L, not network. On a single-user developer laptop, this step alone kills the chain.
Conditions required:
  • Multi-user host (shared dev box, jump host, CI build host with multiple project tenants)
  • Attacker has shell as a different UID than the Claude Code user
Where this breaks in practice:
  • Modern developer endpoints are single-user — laptops, ephemeral cloud workstations, per-job CI runners
  • Cloud-shell / Codespaces / devcontainers spin a fresh container per user — no co-tenancy at the OS layer
Detection/coverage: None — local presence is assumed, not detected by vuln scanners.
STEP 02

Pre-stage /tmp/claude/ and plant the symlink (or just inotifywait the path)

Attacker creates /tmp/claude/ if absent and either ln -s /home/victim/.ssh/authorized_keys /tmp/claude/response.md (for the destructive write variant) or starts inotifywait -m /tmp/claude/response.md to harvest content the moment the victim runs /copy. The hardcoded path means no race window guessing — the attacker knows exactly where to point.
Conditions required:
  • Write permission on /tmp (default on every Unix)
  • Victim has not yet run /copy in this session (so the file doesn't yet exist with victim ownership)
Where this breaks in practice:
  • Sticky bit on /tmp doesn't help — symlink creation in an empty subdir is unrestricted
  • fs.protected_symlinks=1 (default on most modern Linux) does block the symlink-write variant when the writer is not the symlink owner — significant friction for the integrity impact
Detection/coverage: auditd path=/tmp/claude watchers will catch it; EDR with file-creation telemetry on /tmp will flag the symlink.
STEP 03

Victim runs /copy in Claude Code

The privileged user invokes the /copy slash command, which writes the latest assistant response to /tmp/claude/response.md with mode 0644. If the symlink was pre-planted and protected_symlinks is off, the write follows the link and overwrites the target. If the attacker is just reading, they cat the file or have already captured it via inotify.
Conditions required:
  • Victim actively uses the /copy command
  • Claude Code version 2.1.59–2.1.127
Where this breaks in practice:
  • /copy is not a high-frequency command — many users never invoke it
  • Response content is whatever was in the model output — may or may not contain secrets
Detection/coverage: Process-tree telemetry showing node writing to /tmp/claude/ is the canonical signal.
STEP 04

Loot or pivot

Read variant: attacker harvests whatever was in the conversation — pasted API keys, source under review, internal hostnames. Write variant: attacker has clobbered a file with response text — limited utility because the content is uncontrolled, but authorized_keys, .bashrc, or a CI config can be corrupted into a DoS or, with luck, a partial injection.
Conditions required:
  • Captured content contains something useful, OR target file's corruption produces a usable outcome
Where this breaks in practice:
  • Write-variant payload is *uncontrolled* — attacker can't pick what gets written, only where
  • Secrets in chat responses are user-discipline-dependent, not guaranteed
Detection/coverage: DLP scanning of file accesses on developer endpoints; secret-scanner alerts post-facto.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed. No public reports of active abuse as of 2026-06-30.
Public PoCConceptual PoC in the GHSA writeup and Phoenix Security analysis; trivial to reproduce (ln -s + /copy). No weaponized tooling on GitHub yet.
EPSSNot yet scored by FIRST (CVE is <1 week old); expected <1% given local-only, UI-required vector.
KEV statusNot listed. Local privilege bugs in dev tooling rarely reach KEV.
CVSSGitLab-computed CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:H = 6.1 Medium. No NVD/Anthropic authoritative score published.
Affected versions@anthropic-ai/claude-code 2.1.59 → 2.1.127 (npm)
Fixed version2.1.128 and above. Auto-update users already remediated.
Exposure dataNo Shodan/Censys signature — not a network service. Population = developer workstations and CI runners with Claude Code installed, which Anthropic does not publicly disclose.
Disclosure2026-06-25 via HackerOne; CVE assigned 2026-06-29.
ReporterExternal security researcher via HackerOne (handle redacted in advisory). Coordinated disclosure with Anthropic.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (5.5/10)

The single most decisive factor is local-only attack vector with required victim interaction (AV:L/UI:R) on a developer-endpoint product — there is no network reachability, no privilege escalation to root, and the impacted population is single-user developer machines where co-tenancy is rare. The blast radius does not extend beyond the local user's secrets or one chosen file.

HIGH technical mechanism (symlink + insecure temp file is well-understood)
HIGH affected version range (vendor-confirmed in GHSA)
MEDIUM real-world exposure population — Claude Code install base on multi-user hosts is unpublished

Why this verdict

  • Local + UI-required: the chain cannot start without a co-resident unprivileged shell AND the victim choosing to run /copy. That is two compounding gates that exclude >99% of Claude Code installs (single-user laptops, ephemeral CI containers).
  • Blast radius capped at one user: worst case is disclosure of one conversation or destructive write to one victim-owned file. No root, no lateral movement, no fleet impact.
  • Role multiplier — developer workstation: even in the high-value role enumeration, Claude Code is canonically a *developer endpoint* tool, not a domain controller, hypervisor, IdP, PAM, backup admin, or kernel-mode agent. The component does not occupy any high-value role in the noisgate catalog, so no role-floor applies. Worst credible deployment is a shared bastion or shared CI runner — still bounded to that one host's secrets.
  • Modern OS defenses partially mitigate: Linux fs.protected_symlinks=1 (default in essentially every distro since 2012) neutralizes the symlink-write variant when the writer UID ≠ symlink owner UID, leaving only the disclosure variant on those hosts.
  • No KEV, no in-the-wild, EPSS expected near-zero: this is a hygiene bug, not an active campaign.

Why not higher?

HIGH would require either network reachability, a privilege escalation to root, or a high-value-role component (IdP, hypervisor, CA, edge appliance). None apply: vector is AV:L, impact is bounded to the invoking user's data and one target file, and the affected component is a dev CLI — not in the noisgate high-value-role catalog. Calling this HIGH would devalue the bucket reserved for actively-exploited remote vulns.

Why not lower?

LOW understates the integrity impact (I:H in the CVSS write — authorized_keys clobber is a plausible outcome on hosts without protected_symlinks) and the realistic disclosure of pasted API keys/PII from chat history. Co-tenant shells do exist on shared bastions, build hosts with multi-tenant runners, and lab boxes. MEDIUM captures the genuine but bounded risk.

05 · Compensating Control

What to do — in priority order.

  1. Upgrade @anthropic-ai/claude-code to 2.1.128 or later fleet-wide — Per noisgate remediation SLA for MEDIUM, you have up to 365 days — but this is a one-line npm i -g @anthropic-ai/claude-code@latest or auto-update flip. Do it this sprint. Inventory via npm ls -g on managed dev endpoints and CI images.
  2. Confirm fs.protected_symlinks=1 on every Linux dev host and CI runnersysctl fs.protected_symlinks should return 1. This is default on modern distros but verify, especially on hardened-minimal containers. Neutralizes the symlink-write variant immediately without waiting on the npm update.
  3. On shared multi-user hosts, set /tmp to per-user namespaces — Use systemd-tmpfiles PrivateTmp=yes for services, or pam_namespace.so for interactive shells. Removes the co-tenancy precondition entirely. Apply during the same 365-day remediation window — there is no mitigation SLA at the MEDIUM bucket.
  4. Educate developers: don't paste live secrets into Claude Code prompts — The disclosure impact is proportional to what's in the conversation. Reinforce data-handling policy; pair with a secret-scanner pre-commit hook on dev endpoints.
What doesn't work
  • WAF, NGFW, network segmentation — vector is local; no packets cross the wire.
  • MFA / IdP hardening — bug doesn't traverse the auth plane.
  • EDR alone without /tmp file-creation telemetry — many EDRs deprioritize /tmp write events as noise.
  • Removing the /copy command from workflow — users still on 2.1.59–2.1.127 are not the only attack surface; the underlying directory persists across sessions and other commands may share the pattern in older builds.
06 · Verification

Crowdsourced verification payload.

Run on each Linux/macOS dev workstation and CI runner that has Claude Code installed. Invoke as the user that owns the Claude Code install: bash check-cve-2026-46406.sh. No root required; uses npm ls -g and a version comparator. Outputs VULNERABLE, PATCHED, or UNKNOWN.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-cve-2026-46406.sh — detect @anthropic-ai/claude-code versions vulnerable to CVE-2026-46406
# Vulnerable: 2.1.59 <= version <= 2.1.127
# Fixed:      2.1.128+
set -u

PKG="@anthropic-ai/claude-code"
FIXED="2.1.128"
MIN_VULN="2.1.59"

verlt() { # returns 0 if $1 < $2
  [ "$1" = "$2" ] && return 1
  printf '%s\n%s\n' "$1" "$2" | sort -V -C
}

if ! command -v npm >/dev/null 2>&1; then
  echo "UNKNOWN: npm not found"; exit 2
fi

VER=$(npm ls -g --depth=0 --json 2>/dev/null \
      | grep -A1 "\"$PKG\"" | grep version | head -1 \
      | sed -E 's/.*"version": "([^"]+)".*/\1/')

if [ -z "${VER:-}" ]; then
  # try local project install
  VER=$(npm ls --depth=0 --json 2>/dev/null \
        | grep -A1 "\"$PKG\"" | grep version | head -1 \
        | sed -E 's/.*"version": "([^"]+)".*/\1/')
fi

if [ -z "${VER:-}" ]; then
  echo "UNKNOWN: $PKG not installed on this host"; exit 0
fi

if verlt "$VER" "$MIN_VULN"; then
  echo "PATCHED: $PKG $VER (predates vulnerable range)"; exit 0
fi
if verlt "$VER" "$FIXED"; then
  echo "VULNERABLE: $PKG $VER (range 2.1.59-2.1.127, fix in $FIXED)"; exit 1
fi
echo "PATCHED: $PKG $VER (>= $FIXED)"; exit 0
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: treat this as backlog hygiene, not a fire drill. Per the noisgate mitigation SLA for MEDIUM there is no mitigation deadline — go straight to the noisgate remediation SLA of ≤ 365 days, but realistically close this within the next sprint: push @anthropic-ai/claude-code ≥ 2.1.128 to every developer endpoint and CI image (auto-update channel users are already done), verify fs.protected_symlinks=1 on every Linux host, and audit any shared bastion or multi-tenant runner where Claude Code is installed. Skip the change-board theatrics; this is an npm bump. If you operate shared dev hosts, also enforce per-user /tmp via pam_namespace so the next bug like this doesn't matter.

Sources

  1. GitLab Advisory — CVE-2026-46406
  2. CIRCL Vulnerability Lookup — GHSA-4vp2-6q8c-pvq2
  3. Phoenix Security — Three CVEs in Claude Code CLI
  4. Zscaler ThreatLabz — Claude Code Leak analysis
  5. Check Point Research — Critical Claude Code Flaws
  6. CSO Online — Claude Code MCP security problem
  7. CWE-59 — Improper Link Resolution Before File Access
  8. CWE-377 — Insecure Temporary File
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.