Source Map Exposure
JavaScript source maps are generated during the build process to map compiled, minified bundles back to their original source files. When accidentally deployed to production, they disclose the full original source code of the application — including internal architecture, business logic, hardcoded strings, API endpoints, and developer comments. This is a deployment misconfiguration, but the impact is equivalent to a full source code disclosure. The Claude Code incident in 2025 is a documented real-world example where a publicly accessible .map file exposed the full TypeScript source of the application.
What Source Maps Contain
A .map file is JSON. The critical field is sourcesContent — it embeds the complete original source of every file that contributed to the bundle:
{
"version": 3,
"sources": ["../../src/auth/login.ts", "../../src/api/client.ts"],
"sourcesContent": [
"// Full original TypeScript source...",
"// Full original TypeScript source..."
],
"mappings": "AAAA,SAAS..."
}
Downloading a single .map file can expose hundreds of original source files at once, complete with file paths that reveal the internal project structure.
Detect Source Map References in JavaScript
Build tools append a sourceMappingURL comment to the end of each bundle. Check deployed JS files for this reference first:
// ... minified code ... //# sourceMappingURL=main.chunk.js.map
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allow insecure TLS connections by skipping certificate verification. |
| https://$DOMAIN/static/js/main.chunk.js | Target URL with variable domain to fetch the React main chunk JS file. |
{
"version": 3,
"sources": [
"../../src/auth/login.ts",
"../../src/api/client.ts",
"../../src/utils/crypto.ts"
],
"sourcesContent": ["import React...", "const API_KEY = 'sk-prod-...'"]
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allows insecure SSL connections by skipping certificate verification. |
| https://$DOMAIN/static/js/main.chunk.js.map | Target URL with variable domain to fetch the React source map file. |
| -m json.tool | Invokes Python's built-in JSON pretty-printer module. |
| -20 | Limits output to the first 20 lines via head command. |
Discover All JS Files and Check Each
Crawl all JavaScript files served by the application and check each for a sourceMappingURL comment:
/static/js/main.chunk.js /static/js/runtime-main.js /static/js/2.chunk.js
Explain command
| -s | Silent mode; suppresses progress and error output. |
| -k | Allow insecure TLS connections, skipping certificate verification. |
| https://$DOMAIN/ | Target URL with variable domain placeholder over HTTPS. |
| -oE | Enables extended regex (-E) and prints only matching parts (-o). |
| '/[^"]+\.js' | Regex pattern matching JS file paths starting with a forward slash. |
| -u | Removes duplicate lines, outputting only unique sorted results. |
/static/js/main.chunk.js -> sourceMappingURL=main.chunk.js.map /static/js/2.chunk.js -> sourceMappingURL=2.chunk.js.map
Common Map File Locations
Try predictable paths when no explicit reference is found:
404 /static/js/main.js.map 200 /static/js/bundle.js.map 404 /assets/app.js.map
Automated Detection with nuclei
[js-source-map] [info] https://example.com/static/js/main.chunk.js.map
Explain command
| -u https://$DOMAIN/ | Target URL to scan, with domain as a variable placeholder. |
| -tags exposure,js | Run only templates tagged with 'exposure' or 'js'. |
| -severity info,low,medium | Filter templates by severity: info, low, and medium only. |
Extract and Reconstruct Source with sourcemapper
sourcemapper is the most practical tool for pentest use — it downloads the map file and reconstructs the full directory structure locally, exactly as it existed in the original codebase:
[+] Fetching source map from https://example.com/static/js/main.chunk.js.map [+] Extracting 47 source files [+] Writing src/auth/login.ts [+] Writing src/api/client.ts [+] Writing src/config/constants.ts [+] Done
Explain command
| -url | URL of the JavaScript source map file to fetch and parse. |
| https://$DOMAIN/static/js/main.chunk.js.map | Target source map URL with variable domain placeholder. |
| -output | Directory path where extracted source files will be written. |
| /tmp/sourcemap_dump/ | Destination directory for the dumped source map contents. |
The output directory contains the full reconstructed source tree. Browse it like a normal codebase. For multiple map files, run sourcemapper once per map URL.
Alternative — unwebpack-sourcemap
Explain command
| --break-system-packages | Allow pip to modify system-managed Python packages, bypassing PEP 668 guard. |
| https://$DOMAIN/static/js/main.chunk.js.map | Remote URL of the webpack source map file to decompile. |
| /tmp/sourcemap_dump/ | Local output directory where reconstructed source files will be written. |
Search Extracted Source for Sensitive Content
After reconstruction, grep the source files for credentials, keys, internal endpoints, and developer notes:
src/config/constants.ts:3:const API_KEY = 'sk-prod-xK2aB1cD3eF4gH5i';
Explain command
| -r | Recursively search through directories. |
| -n | Print line numbers alongside matching lines. |
| -i | Perform case-insensitive pattern matching. |
| -E | Interpret pattern as an extended regular expression (ERE). |
| '(api_key|apikey|secret|password|token|auth)[[:space:]]*[=:][[:space:]]*["'"'][^"'"']{8,}' | Regex matching common credential keys assigned to quoted values ≥8 chars. |
| /tmp/sourcemap_dump/ | Target directory path to search recursively. |
src/auth/login.ts:47:// TODO: remove debug bypass before prod src/api/client.ts:12:// internal admin endpoint - not exposed in frontend src/utils/crypto.ts:8:// FIXME: rotate this key
Explain command
| -r | Recursively search through directories. |
| -n | Print line numbers alongside matching lines. |
| -i | Case-insensitive pattern matching. |
| -E | Use extended regular expressions for the pattern. |
| 'TODO|FIXME|HACK|internal|admin|debug|bypass' | Regex pattern matching sensitive or debug-related keywords. |
| /tmp/sourcemap_dump/ | Target directory to search within. |
| head -20 | Limit output to the first 20 matching lines. |
src/api/client.ts:5:const BASE_URL = 'https://api.internal.company.com/v2';
Explain command
| -r | Recursively search through directories. |
| -n | Prefix each output line with its line number. |
| -i | Perform case-insensitive pattern matching. |
| -E | Interpret the pattern as an extended regular expression. |
| 'https?://[a-z0-9.-]+\.(internal|local|corp|intranet)' | Regex matching internal/private hostnames over HTTP or HTTPS. |
| /tmp/sourcemap_dump/ | Target directory to search for internal URL references. |
Internal API endpoints discovered in source code feed directly into API endpoint enumeration — these paths often exist but are not linked from the frontend. Developer comments about bypasses, disabled checks, and TODO items are immediate vulnerability research targets.
Format Reconstructed Code
Extracted source is sometimes unformatted. Run prettier for readability before reviewing:
Explain command
| --write | Overwrite files in-place with formatted output instead of printing to stdout |
| '/tmp/sourcemap_dump/**/*.{ts,js,tsx,jsx}' | Glob pattern targeting TS/JS/TSX/JSX files recursively under the directory |
| 2>/dev/null | Redirects stderr to /dev/null, suppressing error messages |
References
-
sourcemappergithub.com/denandz/sourcemapper (opens in new tab)
Go tool for fetching and reconstructing source from exposed map files
-
MDN — Source Mapsdeveloper.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map (opens in new tab)
Source map format and sourcesContent field documentation
-
Webpack — devtoolwebpack.js.org/configuration/devtool (opens in new tab)
Build configuration for controlling source map generation in production
Was this helpful?
Your feedback helps improve this page.