Skip to content
HackIndex logo

HackIndex

Source Map Exposure

6 min read May 15, 2026

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:

┌──(kali㉿kali)-[~]
└─$ curl -sk https://$DOMAIN/static/js/main.chunk.js | tail -3
// ... 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.
┌──(kali㉿kali)-[~]
└─$ curl -sk https://$DOMAIN/static/js/main.chunk.js.map | python3 -m json.tool | head -20
{
  "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:

┌──(kali㉿kali)-[~]
└─$ curl -sk https://$DOMAIN/ | grep -oE '/[^"]+\.js' | sort -u
/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.
┌──(kali㉿kali)-[~]
└─$ for jsfile in /static/js/main.chunk.js /static/js/runtime-main.js /static/js/2.chunk.js; do
mapref=$(curl -sk https://$DOMAIN$jsfile | grep -o 'sourceMappingURL=.*')
[ -n "$mapref" ] && echo "$jsfile -> $mapref"
done
/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:

┌──(kali㉿kali)-[~]
└─$ for path in /static/js/main.js.map /static/js/bundle.js.map /assets/app.js.map /js/app.min.js.map /dist/main.js.map /build/static/js/main.chunk.js.map; do
code=$(curl -skI https://$DOMAIN$path | grep HTTP | awk '{print $2}')
echo "$code $path"
done
404 /static/js/main.js.map
200 /static/js/bundle.js.map
404 /assets/app.js.map

Automated Detection with nuclei

┌──(kali㉿kali)-[~]
└─$ nuclei -u https://$DOMAIN/ -tags exposure,js -severity info,low,medium
[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:

┌──(kali㉿kali)-[~]
└─$ git clone https://github.com/denandz/sourcemapper && cd sourcemapper && go build
┌──(kali㉿kali)-[~]
└─$ ./sourcemapper -url https://$DOMAIN/static/js/main.chunk.js.map -output /tmp/sourcemap_dump/
[+] 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

┌──(kali㉿kali)-[~]
└─$ pipx install unwebpack-sourcemap
┌──(kali㉿kali)-[~]
└─$ unwebpack_sourcemap https://$DOMAIN/static/js/main.chunk.js.map /tmp/sourcemap_dump/
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:

┌──(kali㉿kali)-[~]
└─$ grep -rn -iE '(api_key|apikey|secret|password|token|auth)[[:space:]]*[=:][[:space:]]*["'"'"'][^"'"'"']{8,}' /tmp/sourcemap_dump/
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.
┌──(kali㉿kali)-[~]
└─$ grep -rn -iE 'TODO|FIXME|HACK|internal|admin|debug|bypass' /tmp/sourcemap_dump/ | head -20
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.
┌──(kali㉿kali)-[~]
└─$ grep -rn -iE 'https?://[a-z0-9.-]+\.(internal|local|corp|intranet)' /tmp/sourcemap_dump/
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:

┌──(kali㉿kali)-[~]
└─$ npx prettier --write '/tmp/sourcemap_dump/**/*.{ts,js,tsx,jsx}' 2>/dev/null
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