SourceMap Radar
A Chrome & Edge extension that automatically scans every page you visit for exposed JavaScript and CSS source maps — and verifies which ones are actually retrievable.
Download
- Chrome 110+, Edge, Brave, or any Chromium browser
- Developer mode enabled
- No Node, npm, or build step
Not on the Chrome Web Store — it's loaded unpacked on purpose, so you can read every line before
granting it <all_urls>. Browse the source above first.
Install in your browser
-
1
Download and unzip
Unzip
sourcemap-radar.zipanywhere you'll keep it — the browser loads the folder from disk every launch, so don't delete it afterwards. -
2
Open the extensions page
Chromechrome://extensionsEdgeedge://extensionsBravebrave://extensionsPaste it into the address bar — these URLs can't be opened from a link.
-
3
Turn on Developer mode
Toggle in the top-right of the extensions page (bottom-left sidebar on Edge).
-
4
Load unpacked
Click Load unpacked and select the
sourcemap-radarfolder — the one containingmanifest.json, not its parent. -
5
Pin it
Open the puzzle-piece menu in the toolbar and pin SourceMap Radar, so the badge count stays visible while you browse.
Troubleshooting
"Manifest file is missing or unreadable" — you selected the wrong folder. Pick the one with manifest.json directly inside it.
Badge never appears — the extension only scans http(s) pages. It cannot read chrome:// pages, the Web Store, or other extensions' pages.
Nothing found on a page you know has maps — the assets were served from cache before the extension attached. Reload the tab, then press Rescan.
After editing the source — hit the reload arrow on the extension's card, then reload the target page.
Firefox — not supported as-is. It uses the Chromium chrome.* MV3 service-worker model.
How to use it
-
1
Just browse the target
Auto-scan is on by default. Every JS and CSS file the page loads gets probed as soon as the page settles. The toolbar badge shows how many retrievable maps were found — red when it's more than zero.
-
2
Open the popup for the breakdown
Four counters across the top — exposed, declared only, clean, and total assets seen. Each finding lists how many original sources the map contains and how many carry embedded content.
-
3
Pull the evidence
Per finding: Copy map URL, Open, Download .map. Page-wide: Export JSON for your report. Then unpack the
.mapback into original source with the JS SourceMap Unmapper. -
4
Behind a login? Turn on Authenticated scan
Log into the target as normal, then enable Authenticated scan in the popup. Findings that needed the session get an auth chip, because "exposed to anyone" and "exposed to logged-in users" are different findings.
Reading the verdicts
| Tag | What it means | Impact |
|---|---|---|
| exposed | Map fetched and parsed as a real source map. | Original source recoverable. Report it. |
| inline | Map is base64/URL-encoded inside the asset itself. | Same as exposed — nothing to fetch, it already shipped. |
| declared | Comment points at a map, but it 404s or isn't valid JSON. | Low — leaks build paths and filenames only. |
| clean | No comment, and nothing at the conventional .map path. |
None. |
| error | The asset itself couldn't be re-fetched. | Inconclusive — often auth. Try an authenticated scan. |
Settings
| Toggle | Default | Effect |
|---|---|---|
| Findings only | ON | Hides clean assets. Turn off to audit everything that was checked. |
| Auto-scan | ON | Scans on page load. Off = only when you press Rescan, for quieter engagements. |
| Guess .map | ON | Tries <asset>.map when no comment exists — pipelines often strip the comment but still deploy the file. |
| Include CSS | ON | Also probes stylesheets. Sass/Less maps leak original selectors and structure. |
| Authenticated scan | OFF | Re-fetches with your session cookies — but only to the page's own domain and its sub/parent domains. |
| All origins | OFF | Lifts that restriction and sends cookies to every asset host. See the warning below. |
On "All origins": a page loads scripts from CDNs, tag managers and analytics hosts it doesn't control. That toggle sends your session cookies to all of them. Leave it off unless you own every asset host in scope — the default already covers the target's own domain and its subdomains.
How the detection works
01 Collect
Assets come from two sources: the live webRequest stream, and a DOM + Resource-Timing sweep in the content script. The second one catches cache hits, back/forward restores and late SPA chunks the first one misses.
02 Tail-read
A Range: bytes=-4096 request pulls only the end of each bundle, where the comment lives — instead of downloading megabytes. Falls back to a size-capped full fetch when the server ignores Range.
03 Match
Handles //#, /*# … */ and legacy //@ forms, plus data: URIs for inlined maps. Quoted occurrences inside code are skipped as false positives.
04 Verify — the important part
A map only counts when the response parses as JSON and looks like a source map. This is what stops SPAs that answer every path with index.html from producing a page of false positives — the usual failure of naive .map scanners.
Findings report the source count, how many entries carry sourcesContent
(meaning the full original file is recoverable, not just its name), map size, and a sample of source paths.
Concurrency is capped at 6 requests and 400 assets per tab, so a scan won't hammer a target. Results live
in session storage and clear on navigation.