# Content Security Policy header present and allows essential resources

- **Pattern:** `ab-002477` (`seo-advanced.technical-seo.content-security-policy`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002477
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002477)

## Why it matters

A missing Content Security Policy header leaves the application exposed to cross-site scripting via CWE-693 (Protection Mechanism Failure) and is a finding under OWASP A05 (Security Misconfiguration). CSP restricts which scripts, styles, and resources the browser will execute — without it, any XSS vector can load arbitrary scripts from external origins. For SEO, a compromised site that injects spam links or redirects risks Google Safe Browsing flagging, which removes the site from SERPs entirely until manual review clears it. A CSP that blocks analytics scripts is also a failure mode — it silently stops tracking data without an error.

## Severity rationale

Low in this audit context because CSP is a defense-in-depth control and its absence doesn't constitute an active vulnerability — but any existing XSS vector becomes higher-impact without it.

## Remediation

Add CSP headers in `next.config.js` using the `headers()` async function. Start with a report-only policy to detect violations before enforcing:

```js
// next.config.js
async headers() {
  return [{
    source: '/(.*)',
    headers: [{
      key: 'Content-Security-Policy',
      value: [
        "default-src 'self'",
        "script-src 'self' 'unsafe-inline' *.google-analytics.com *.vercel-insights.com",
        "style-src 'self' 'unsafe-inline'",
        "img-src 'self' data: https:",
        "font-src 'self' fonts.gstatic.com",
        "connect-src 'self' *.supabase.co *.google-analytics.com",
      ].join('; ')
    }]
  }]
}
```

Verify with `curl -I https://yoursite.com | grep -i content-security-policy`. Add `report-uri` to a CSP reporting endpoint (e.g., Report URI) to catch violations from real users before tightening the policy.

## Detection

- **ID:** `content-security-policy`
- **Severity:** `low`
- **What to look for:** Count all locations where Content-Security-Policy could be configured: `next.config.js` headers, middleware, `<meta http-equiv="Content-Security-Policy">` tags, and deployment config (`vercel.json`, `netlify.toml`). Enumerate the CSP directives found (e.g., `default-src`, `script-src`, `style-src`). Verify the policy does not block analytics scripts, monitoring tools, or other essential resources.
- **Pass criteria:** CSP header is present in at least 1 configuration location with at least 3 directives defined, and the policy does not block essential external resources (analytics, CDN assets, font providers). Report: "CSP configured with X directives; 0 essential resources blocked."
- **Fail criteria:** No CSP header found in any configuration, or CSP blocks at least 1 essential resource (analytics, CDN, fonts).
- **Skip (N/A) when:** No external resources are loaded by the application (no analytics, no external scripts, no CDN assets).
- **Detail on fail:** `"No Content-Security-Policy header found in next.config.js, middleware, or deployment config"` or `"CSP script-src blocks Google Analytics (*.google-analytics.com not in allowlist)"`.
- **Remediation:** Add CSP header in `next.config.js` headers configuration:

  ```js
  // next.config.js
  async headers() {
    return [{
      source: '/(.*)',
      headers: [{
        key: 'Content-Security-Policy',
        value: "default-src 'self'; script-src 'self' *.google-analytics.com; style-src 'self' 'unsafe-inline'"
      }]
    }]
  }
  ```

## External references

- cwe CWE-693
- owasp A05

Taxons: injection-and-input-trust, operational-readiness

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