Website problems

Publicly accessible source maps

A source map is a file that maps minified JavaScript or CSS back to the original source, so a browser's debugger can show readable code. When it includes the `sourcesContent` field — which most build tools produce by default — it contains the complete original source text, comments included. Serving one publicly therefore publishes your source code at a predictable URL. It is not a vulnerability by itself; it is a disclosure that makes finding vulnerabilities considerably easier.

What a source map actually contains

A mapping between positions in the generated file and positions in the original files. That alone is fairly harmless.

The original file paths, which reveal the project structure, the framework, and frequently the developer's directory layout and username.

`sourcesContent`: the full text of every original file, embedded in the map. This is the part that matters, and it is on by default in most bundlers.

So a `.js.map` with `sourcesContent` is not a debugging aid that leaks hints. It is the source, in a JSON wrapper, reachable by anyone who requests the URL.

The same applies to CSS source maps, which are less sensitive but reveal the same structure.

Why it is usually there by accident

Build tools generate maps by default in many configurations, and the production build inherits the setting from the development one.

Deployment copies the output directory wholesale, so whatever the build produced is served.

The bundle itself ends with a `sourceMappingURL` comment naming the map, so nobody has to guess the filename — the browser is told where to look, and so is everyone else.

Teams that deliberately want maps for error reporting upload them to the error service and forget to exclude them from the public deploy, which is the most common variant of this.

And because the map is only fetched when a debugger is open, it costs no bandwidth and appears in no performance report. Nothing surfaces it.

What it exposes in practice

Business logic: pricing rules, discount conditions, feature gates, validation that the server may or may not repeat.

API structure: endpoint paths, parameter names, request shapes — the map of the attack surface, without any guessing.

Comments, which are frequently more candid than the code. `// temporary bypass, remove before launch` is a real category of finding.

Client-side keys and identifiers. These are often public by design, and the map makes it easy to distinguish the ones that are from the ones that were assumed to be.

Internal hostnames and paths from the original file structure, which point at infrastructure not meant to be named.

None of this is a vulnerability. All of it removes the reconnaissance step.

How to check it yourself

Look at the end of a production bundle for `//# sourceMappingURL=`. That names the map file.

Request it: `curl -I https://example.com/assets/app.js.map`. A 200 means it is public.

If it returns content, check whether `sourcesContent` is populated: `curl -s <url> | head -c 2000` shows the beginning of the JSON, and the presence of that key with file text after it is the finding.

Try the conventional names even where no comment points at them — appending `.map` to each bundle URL is what an automated scan does.

Check CSS as well as JavaScript, and check every deployed environment: staging and preview builds are frequently more permissive than production and equally public.

How to fix it and keep debugging

The goal is not to lose source maps — they are genuinely valuable for diagnosing production errors. It is to stop serving them to everyone.

Generate them, upload them to the error-tracking service, and exclude them from the deployed artefact. Most error services have a build plugin that does exactly this.

Alternatively, serve them only behind authentication, or restrict them by IP at the edge.

If you must generate them into the public output, disable `sourcesContent` so the map carries positions without the source text. Debugging is degraded and the disclosure is not total.

Then rotate anything the map exposed that should not have been public — keys, tokens, internal endpoint names — because assuming nobody fetched it is not a control.

Add a check to the deployment that fails if a `.map` file is present in the public output. This is one line and it is the only part of the fix that survives a new developer.

How VeriFixScan detects it

`exposure.sourcemap.public` looks for source maps referenced by the scripts and stylesheets each crawled page loads, and requests them to confirm whether they are publicly reachable.

`exposure.sourcemap.sources_content` reports whether a reachable map carries the embedded original source, which is the difference between a structural hint and a full disclosure.

`exposure.assets.coverage` reports the assets examined, so a clean result reads as 'none found among what was checked' rather than as an unqualified all-clear.

The check requests files as any client can. It does not attempt to guess credentials or bypass anything.

Frequently asked questions

Are public source maps a security vulnerability?
Not in themselves. They are an information disclosure: the code, the API shape and the comments become readable, which removes the reconnaissance an attacker would otherwise have to do.
Can I keep source maps for error tracking?
Yes, and that is the right approach. Generate them, upload them to the error service, and exclude them from the public deployment.
Is disabling sourcesContent enough?
It removes the embedded source text, which is the bulk of the disclosure. The file paths and structure remain, so not serving the map at all is still better.

Sources

Related

VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.

Scan a website