The Claude Code Leak: What One Missing File Cost Anthropic, and How to Check If You're Exposed
BlogSupply Chain Security

The Claude Code Leak: What One Missing File Cost Anthropic, and How to Check If You're Exposed

On March 31, 2026, Anthropic shipped the complete source code of Claude Code to every npm mirror on the planet. Not through a breach. Not through a compromised pipeline. Through a missing .npmignore file.

Version 2.1.88 of @anthropic-ai/claude-code included a 59.8 MB source map containing 512,000 lines of unobfuscated TypeScript across ~1,900 files. The full agent architecture, 44 unreleased feature flags, internal model codenames, system prompts, and safety guardrails were now public. Within hours the code was forked over 41,500 times. A clean-room rewrite hit 50,000 GitHub stars in two hours.

Anthropic’s head of Claude Code, Boris Cherny, called it “plain developer error.” He’s right. And that’s exactly why it matters.

How it happened

Claude Code is built on Bun, the JavaScript runtime Anthropic acquired in December 2025. Bun generates source maps by default during builds. Source maps are JSON files that map minified production code back to the original source, line by line. They’re meant for internal debugging.

The problem: Anthropic’s release pipeline had no .npmignore file and no "files" whitelist in package.json. When you run npm publish without either of those, npm ships everything in the project directory. Build artifacts, source maps, environment files, test fixtures, internal docs. All of it.

So when a developer ran the publish command, a single 59.8 MB .map file went along for the ride. That file contained every line of proprietary source code, fully readable.

Security researcher Chaofan Shou, an intern at Solayer Labs, spotted it around 4:23 AM ET and posted on X. By afternoon, Anthropic confirmed the incident. By then, the internet had already dissected the entire codebase.

What was exposed

This wasn’t a leak of API keys or customer data. It was worse from a competitive and security standpoint:

The source revealed Claude Code’s complete tool orchestration and permission model, 44 feature flags gating over 20 unshipped capabilities (giving competitors a full product roadmap), internal model codenames for unreleased versions, and the full system prompt templates including safety mechanisms and permission escalation flows.

For attackers, the code is a recipe book. With the tool execution logic exposed, anyone can now design malicious repositories that manipulate Claude Code into running background commands or exfiltrating data.

This is not an Anthropic-only problem

Here’s why we’re writing about this: we see the same packaging mistakes across our client base. If your organization publishes packages to npm, PyPI, RubyGems, Maven Central, Docker Hub, or any public registry, you may be leaking source code, credentials, or internal configuration right now without knowing it.

The default behavior of most package managers is to include everything unless told otherwise. That’s a dangerous default.

How to check if your npm packages are leaking

At Profero, our External Attack Surface team runs these checks against client organizations. Here’s how you can do it yourself.

Step 1: Find your packages

# List all packages under your npm scope
curl -s "https://registry.npmjs.org/-/v1/search?text=scope:your-org&size=250" \
  | jq '.objects[].package.name'

# Cross-reference with GitHub CI configs
gh search code "npm publish" --owner=your-org

Step 2: Inspect what you’re actually shipping

# Download a package without installing it (safe, no scripts run)
npm pack @your-org/package-name

# List every file in the tarball
tar -tzf your-org-package-name-*.tgz

Step 3: Look for red flags

Report immediately if you find:

File patternRisk
*.map (source maps)Full original source code
.env, .env.*API keys, database credentials
.pem, .key, .p12, .pfxTLS certificates, private keys
credentials.json, service-account.jsonCloud provider credentials
.npmrc with auth tokensRegistry auth tokens
id_rsa, id_ed25519SSH private keys
.git/ directoryFull git history including deleted secrets

Flag for review:

File patternRisk
/src/ with TypeScript sourceIP exposure
/test/, /__tests__/Hardcoded test credentials, internal URLs
tsconfig.json, webpack.config.jsArchitecture disclosure
Sudden package size spike between versionsAccidental build artifact inclusion

Step 4: Extract and read source maps

If you find .map files, they likely contain your entire codebase. Here’s how to reconstruct the original source:

# Check how many original source files are embedded
cat package/dist/index.js.map | jq '.sourcesContent | length'

# Reconstruct every file
python3 -c "
import json, os, sys
with open(sys.argv[1]) as f:
    sm = json.load(f)
for src, content in zip(sm.get('sources',[]), sm.get('sourcesContent',[])):
    if content:
        path = f'reconstructed/{src}'
        os.makedirs(os.path.dirname(path), exist_ok=True)
        with open(path, 'w') as f:
            f.write(content)
        print(f'  Extracted: {src}')
" package/dist/index.js.map

Step 5: Check your version history

Secrets may have shipped in an older version and been removed later. The old version is still on the registry:

# List all published versions
npm view @your-org/package-name versions --json

# Download and compare specific versions
npm pack @your-org/package-name@1.2.3
npm pack @your-org/package-name@1.2.4
diff <(tar -tzf *1.2.3.tgz | sort) <(tar -tzf *1.2.4.tgz | sort)

If the "files" field was added recently, everything before that version was probably exposed.

Five things to fix this week

1. Switch from blacklist to whitelist. Replace .npmignore with a strict "files" array in package.json. Only list the distribution files your consumers need. New build artifacts are excluded by default.

2. Turn off source maps in production builds. Configure Bun, Webpack, esbuild, or whatever you use to skip .map generation for release artifacts. If you need source maps for error monitoring, upload them to Sentry or Datadog privately.

3. Add npm pack --dry-run to your CI pipeline. This lists exactly which files will ship. Fail the build if unexpected files appear. It takes five minutes to set up and would have prevented the Claude Code leak entirely.

4. Set a package size gate. If your package suddenly grows from 2 MB to 60 MB, something is wrong. Tools like size-limit or bundlewatch catch this automatically.

5. Require two-person approval for publishes. No single developer should be able to push to a public registry alone. Use npm’s organization-level permissions and require a CI approval step before the publish command runs.

These controls apply to every registry: npm, PyPI, RubyGems, Maven Central, Docker Hub. Review .dockerignore, MANIFEST.in, and equivalent exclusion mechanisms across all your publishing pipelines.

The bigger lesson

Anthropic is a $60B+ company with some of the best engineers in AI. They still shipped their entire source code because of one missing config file after a build system migration. If it can happen to them, it can happen to you.

The fix isn’t more process. Boris Cherny said it himself: “find ways to go faster, rather than introducing more process.” Automate the checks. Make the CI pipeline refuse to publish a package that contains files it shouldn’t. Make the safe path the easy path.

If you’d like Profero to audit your organization’s external attack surface, including public package registry exposure, contact us.


The Profero Incident Response team has responded to hundreds of cyber incidents worldwide since 2020. Our Rapid-IR platform combines cloud-based technologies, threat intelligence, and field experience to help organizations prevent, detect, and respond to the most advanced threats.