← All security check guides

Is a site's source map public?

A source map is a companion file that maps minified code back to what a developer wrote. It exists so that a stack trace in the browser points at a real line in a real file. When it is deployed alongside the bundle, anyone can fetch it and rebuild the readable original, and where the map carries sourcesContent, the original is inside the map itself.

What a published map gives away

The first thing it hands over is structure: file names, folder layout, component and function names, the shape of the internal API. Minification removes all of that, and a map puts it back. Work that would take an attacker a careful afternoon becomes a single download.

The second thing is whatever was written in the source but never meant to be read. Comments explaining why a check is skipped, a commented-out endpoint, a note naming an internal host, an old credential left in a disabled block. None of it survives minification, and all of it comes back with sourcesContent.

On its own a source map is rarely the breach. It is the reconnaissance step that makes the next finding cheap, which is why it sits at medium on its own and rises when the source travels with it.

Confirmed as a map, not assumed from a 200

This is the check where a careless implementation produces noise on almost every modern site. A single-page application answers 200 with its own HTML for any address at all, including /assets/index.js.map, so a scanner that treats a 200 as the finding would report a public source map on sites that publish none.

CheckWeb decides from the document itself. The response has to parse as a source map, version 3 with the keys a generator actually writes, before anything is reported. An HTML shell, a 404 page, an unrelated JSON payload and an API response that happens to have a version field are all rejected.

Only the opening of the map is read, and that is deliberate: the file is the site's own source code, and the finding is that it is downloadable, not what is written in it. Where sourcesContent is visible in that opening, the severity rises to high and the report says so. Where it is not, the finding stays at medium rather than assuming the worst about a file we declined to download.

How it looks in the report

The finding names the map, the bundle it belongs to, and whether the source travels inside it. The maps that get checked are the ones the site's own bundles point at, plus the conventional sibling name, because build tools frequently strip the trailing comment and deploy the file anyway.

The source itself is never downloaded, quoted or stored. What the report carries is the URL, the verdict and the size, which is everything an owner needs in order to confirm it from their own browser.

Like the rest of the active layer, this runs after domain ownership is verified. The free passive scan does not fetch a site's bundles or their maps.

Example

Source map is publicly downloadable

The source map for /assets/index-4f2.js is downloadable and carries the original source inline, so the front-end code can be reconstructed in full, comments included. Turn source maps off for the production build or stop uploading the .map files with it.

FAIL

/assets/index-4f2.js.map · valid source map, carries sourcesContent

Published vs kept private

Published

The build writes app.js and app.js.map, and the deploy copies the whole output directory. The bundle ends with a sourceMappingURL comment pointing at the map, the map answers 200, and the readable source is one request away from anybody who looks at the end of the file.

Kept private

The production build writes no map, or writes one and uploads it to the error-reporting service instead of the web server. Stack traces are still readable where they are needed, and the public bundle points at nothing that answers.

Hidden maps are a real middle ground: some tools keep the map on disk without the trailing comment. That is worth knowing about, because the conventional filename is the first thing anyone tries.

How to switch it off

  • Turn maps off for the production build. In Vite set build.sourcemap to false; in Next.js leave productionBrowserSourceMaps off, which is the default; in webpack pick a devtool setting that writes no file; in Create React App set GENERATE_SOURCEMAP to false.
  • Delete the .map files that are already deployed. A configuration change applies to the next build and does nothing about the file sitting on the server right now.
  • Clear the CDN or edge cache for those paths. A cached map keeps answering long after the origin has stopped serving it, and that is the most common reason a fix appears not to have worked.
  • If maps are needed for error reporting, upload them to that service rather than publishing them. Sentry, Rollbar and their equivalents all accept an upload step at build time, which keeps readable stack traces without putting the source on the public web.
  • Read what the map would have exposed before considering the matter closed. Anything a comment named, an old endpoint, an internal host, a credential in a disabled block, has been readable for as long as the file was up and needs handling on its own. (API keys in front-end code covers the credential half of that.)
  • Then re-run the audit and confirm the map no longer answers. The check is one request, and only a request from outside the network can tell a deleted file from a cached one.

Run a free scan

The free passive scan grades headers, TLS and known CVEs on any site in about thirty seconds, with no signup. Verifying that a domain is owned adds the deep scan, which follows the maps a site's own bundles point at and confirms each one is really a map before reporting it.

Check my website

This one needs an active scan

A passive scan reads what a site shows every visitor, and this finding is not in that layer. It takes an active audit, run by the owner on a domain they have verified, to look where it hides.

How the deep audit works →

FAQ

Are source maps a vulnerability?
Not in themselves. A published map does not let anyone in; it makes understanding the application cheap, and it exposes whatever was written in the source and never meant to be read. It is reported at medium for that reason, and at high when the source travels inside the map.
Removing the sourceMappingURL comment hides the map, does it not?
It hides the pointer, not the file. The conventional name is the bundle's name with .map on the end, which is the first thing anyone tries, and the file keeps answering. The map has to be removed or never built.
Does the scan download the source?
No. Only the opening of the map is read, and only far enough to establish that the document really is a source map. The file is the site's own code, and the finding is that it can be downloaded rather than what it contains.
The .map path returns the site's homepage. Is that a finding?
No, and that is the case a careless check gets wrong. A single-page application answers 200 with its own HTML for every address, so the response has to parse as a source map before anything is reported.

Related checks