# Source maps are not publicly accessible in production

- **Pattern:** `ab-000016` (`security-headers.info-exposure.no-source-maps`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-17
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000016
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000016)

## Why it matters

Public source maps let anyone reconstruct your original pre-minified TypeScript or JavaScript from your production bundle — including business logic, API endpoint structure, internal variable names, comments, and any secrets that were inadvertently bundled. An attacker with your source maps can read your application as if they had access to your repository. CWE-540 (Inclusion of Sensitive Information in Source Code) and CWE-538 (File and Directory Information Exposure) both apply. OWASP A05 (Security Misconfiguration) lists public source maps as a common developer oversight. Next.js defaults to `productionBrowserSourceMaps: false` — enabling them is an explicit action that is easy to forget to revert after debugging.

## Severity rationale

High because publicly accessible source maps expose full application logic, comment strings, and internal structure — equivalent to open-sourcing your production code without intending to.

## Remediation

Verify `productionBrowserSourceMaps` is absent or explicitly `false` in `next.config.js`. The default is already `false` — this check fails only when it's been explicitly enabled.

```js
// next.config.js
const nextConfig = {
  // Do NOT set productionBrowserSourceMaps: true
  // productionBrowserSourceMaps: false  // explicit, but redundant
}
```

If you need source maps for error tracking (Sentry, Datadog), use the `hidden-source-map` webpack devtool or upload maps to your error tracking service via their CLI/CI integration without serving them publicly. Remove any `.map` files from the `public/` or `static/` directories if they were committed accidentally.

## Detection

- **ID:** `no-source-maps`
- **Severity:** `high`
- **What to look for:** Check for source map configuration. In Next.js, check `next.config.*` for `productionBrowserSourceMaps` (should be `false` or absent — it defaults to `false`). Count all `.map` files in `public/` and `static/` directories. Check build configuration for source map settings.
- **Pass criteria:** Production source maps are disabled (framework default) or explicitly configured to not be publicly served (e.g., `productionBrowserSourceMaps: false` in Next.js, `devtool: false` or `devtool: 'hidden-source-map'` in webpack). No more than 0 `.map` files should exist in the `public/` or `static/` directories.
- **Fail criteria:** `productionBrowserSourceMaps: true` in Next.js config, or `.map` files found in `public/`, or build config explicitly enables public source maps.
- **Skip (N/A) when:** The project has no JavaScript build step — pure server-rendered HTML, or a backend-only project with no client JS bundling.
- **Detail on fail:** `"next.config.js has productionBrowserSourceMaps: true — source code is publicly readable"` or `"Source map files (*.js.map) found in public/ directory"`
- **Remediation:** Source maps let anyone reconstruct your original source code, exposing business logic, comments, and potentially sensitive patterns. Ensure they're disabled in production:

  ```js
  // next.config.js — remove or set to false
  const nextConfig = {
    productionBrowserSourceMaps: false, // this is the default
  }
  ```

  If you need source maps for error tracking (e.g., Sentry), use hidden source maps that are uploaded to your error tracking service but not served publicly.

---

## External references

- cwe CWE-540
- cwe CWE-538
- cwe CWE-200
- owasp A05

Taxons: operational-readiness

HTML version: https://auditbuffet.com/patterns/ab-000016
