← All posts

Claude Code Source Map Exposure: Why It Happened, How It Can Be Reversed, and How to Disable It When Selling Source Code

Apr 4, 2026claude code source mapsource map exposuredisable source maps production

You ship a Node.js or browser-based product to a customer as a bundled build, assuming the minified output hides your implementation details. A week later, someone opens DevTools, finds a .map file, and reconstructs readable source paths, internal module names, comments, and sometimes fragments of proprietary logic. That is the practical risk behind recent discussion around Claude Code and exposed source maps: the problem is not only debugging metadata being present, but how much internal information that metadata can reveal when distributed carelessly.

This article explains what source maps expose, why this matters when selling software to customers, how reverse engineering works in practice, and what to disable or change in your build pipeline to reduce leakage.

Why did the Claude Code source map issue matter?

The issue mattered because source maps are designed to make transformed code understandable again. In development, that is useful. In customer-facing or distributable builds, it can become a disclosure channel.

A source map usually links minified or transpiled output back to original source locations. Depending on how it is generated, it may include:

  • Original file names and directory structure
  • Function and variable names before minification
  • Inline original source content via sourcesContent
  • Comments accidentally preserved in source files
  • Framework structure, package layout, and internal architecture clues

If the map contains sourcesContent, the impact is much higher. In that case, the original source text may be embedded directly inside the map file. Even without full source text, file paths and symbol mappings can significantly reduce the effort required to understand a protected build.

For teams selling source-limited builds, SDKs, desktop apps, Electron apps, or browser applications to customers, this is both a technical and business problem:

  • Technical impact: easier reverse engineering, easier vulnerability discovery, easier patch bypassing
  • Business impact: loss of proprietary implementation details, weaker licensing control, and reduced differentiation

The root cause is rarely a single tool. It is usually a build configuration decision: source maps enabled in production, uploaded to the same public artifact location, or generated with embedded source content.

What exactly can an attacker recover from a source map?

The answer depends on the source map type and bundler settings, but recovery is often more complete than teams expect.

A typical source map contains:

{
 "version": 3,
 "file": "app.min.js",
 "sources": [
 "src/auth/license-check.ts",
 "src/core/crypto.ts"
 ],
 "sourcesContent": [
 "export function validateLicense(...) { ... }",
 "export function decryptPayload(...) { ... }"
 ],
 "names": ["validateLicense", "decryptPayload", "token", "expiresAt"],
 "mappings": "..."
}

From this, a reverse engineer may recover:

  • The original module layout
  • Readable stack traces
  • Class and function intent from names
  • Security-sensitive logic locations
  • License enforcement code paths
  • Feature gating and premium checks

If sourcesContent is present, recovery becomes straightforward. If it is absent, the map still helps correlate minified code with original symbols and file boundaries. That dramatically lowers manual analysis cost.

Common leakage patterns include:

  • Webpack: devtool accidentally left enabled in production
  • Vite: build.sourcemap: true used for release builds
  • esbuild: maps emitted by default in CI or packaging scripts
  • TypeScript: declaration maps or source maps shipped with published packages
  • Electron: packaged app contains JS bundles plus maps inside app.asar or adjacent resources

The problem is not limited to browser apps. Any distributed JavaScript bundle can leak internal structure if maps are included in the shipped artifact.

How does source map reversal work in practice?

Reverse engineering with source maps is usually not sophisticated. In many cases, it is a matter of locating the map and loading it into standard tooling.

Typical workflow:

  1. Inspect shipped JavaScript for a //# sourceMappingURL=... comment
  2. Fetch the referenced .map file or extract it from the package
  3. Open DevTools, a map explorer, or write a small script to parse the map
  4. Recover file names, source content, and symbol mappings
  5. Trace sensitive logic such as license checks, API signing, or feature flags

For example, a bundled file may end with:

//# sourceMappingURL=app.min.js.map

If the map is accessible, parsing it in Node.js is trivial:

const fs = require('fs');

const map = JSON.parse(fs.readFileSync('./dist/app.min.js.map', 'utf8'));

console.log('Sources:');
for (const src of map.sources || []) {
 console.log('-', src);
}

if (Array.isArray(map.sourcesContent)) {
 console.log('\nEmbedded source files found:', map.sourcesContent.length);
 console.log('\nFirst file preview:\n');
 console.log(map.sourcesContent[0].slice(0, 500));
} else {
 console.log('No embedded source content, but symbol and path metadata may still exist.');
}

Even when source content is not embedded, the names and mappings fields can be used to reconstruct a more readable representation of the code. Browser DevTools can also automatically use the map to display original paths and code views.

Trade-off: source maps are useful for production debugging, especially for error monitoring systems. But if you expose them directly to customers, you are effectively lowering the cost of reverse engineering. The right decision depends on whether you need private observability or public distribution safety. In most cases, you should separate those concerns instead of shipping public maps.

How do you disable source maps safely in production builds?

The safest default for customer-delivered artifacts is simple: do not generate or ship public source maps unless you have a very specific operational reason.

Here are common production settings.

Webpack

// webpack.config.js
module.exports = {
 mode: 'production',
 devtool: false
};

If you need stack trace support for internal monitoring, prefer generating hidden maps and storing them privately, not alongside customer assets.

Vite

// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
 build: {
 sourcemap: false
 }
});

esbuild

require('esbuild').build({
 entryPoints: ['src/index.ts'],
 bundle: true,
 minify: true,
 sourcemap: false,
 outfile: 'dist/app.js'
});

TypeScript

{
 "compilerOptions": {
 "sourceMap": false,
 "inlineSourceMap": false,
 "declarationMap": false
 }
}

Next.js

// next.config.js
module.exports = {
 productionBrowserSourceMaps: false
};

Also check your pipeline for these mistakes:

  • CI artifacts include *.map unintentionally
  • CDN upload rules publish map files automatically
  • Docker images copy the full build directory including maps
  • Desktop app packaging includes maps in resources
  • NPM packages publish source and maps due to a broad files rule

A practical release check is:

find dist -type f \( -name "*.map" -o -name "*.ts" -o -name "*.tsx" \)

If you are distributing code to customers, review the final artifact rather than trusting the build config alone.

What should you do if you still need debugging visibility?

Some teams keep source maps because production debugging without them is painful. That is a real operational need, but public distribution is the wrong place to solve it.

Safer patterns include:

  • Private source map upload: upload maps to an internal error monitoring platform, but never publish them with customer assets
  • Hidden source maps: generate maps without linking them from shipped JavaScript, then store them in a restricted environment
  • No sourcesContent: if maps are absolutely required, avoid embedding original source text
  • Server-side symbolication only: keep all mapping private and resolve stack traces on your own infrastructure

Important limitation: hidden maps are still risky if they are copied into the shipped package or exposed through a predictable URL. “Hidden” only removes the reference comment; it does not protect the file if the file is still accessible.

Another trade-off is supportability. The more aggressively you strip metadata, rename symbols, and remove maps, the harder debugging and incident response become. Teams should explicitly choose where they want visibility: inside their own infrastructure, not in the customer-delivered artifact.

How can you reduce data leakage when selling source or deliverables to customers?

When customers buy a deployable package rather than full source access, source maps are only one part of the exposure surface. You should also review what else reveals internal knowledge.

Recommended controls:

  • Ship only compiled artifacts: avoid bundling raw TypeScript, test files, scripts, and internal docs
  • Remove source maps from release packages: including declaration maps for published libraries
  • Minimize file structure leakage: avoid exposing clear internal module names where possible
  • Separate secrets from code: never rely on bundling-time hiding for API keys or credentials
  • Move critical checks server-side: license validation, entitlement checks, and anti-tamper logic are weaker on the client
  • Review comments and debug strings: they often survive in overlooked files or embedded metadata
  • Lock down package contents: use explicit allowlists for publish and release steps

For example, in package.json, prefer an explicit file list:

{
 "files": [
 "dist/**/*.js",
 "dist/**/*.d.ts",
 "README.md",
 "LICENSE"
 ]
}

And exclude maps if they are generated during intermediate steps:

{
 "files": [
 "dist/**/*.js",
 "dist/**/*.d.ts"
 ]
}

If you sell on-demand deliverables to customers, think in layers:

  1. Do not ship unnecessary metadata
  2. Do not expose original source through maps or package contents
  3. Do not keep critical enforcement purely client-side
  4. Do not assume minification is protection

The main limitation is architectural: if code runs on the customer’s machine, some level of reverse engineering is always possible. The goal is not perfect secrecy. The goal is to avoid unforced disclosures that make analysis substantially easier.

Practical recommendations:

  • Disable production source maps by default for customer-delivered builds
  • If debugging is required, keep maps private and never publish them with assets
  • Audit final release artifacts for .map, raw source files, comments, and internal metadata
  • Move sensitive business logic and license decisions to controlled backend systems where possible
  • Treat source map exposure as a release engineering issue, not just a frontend setting

The recent Claude Code discussion is a reminder of a broader rule: any metadata intended for developer convenience can become a disclosure channel in distributed software. Production builds should be reviewed with the same care as the source code itself.