# Content-Security-Policy header is present

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

## Why it matters

Without a Content-Security-Policy, any XSS vulnerability in your app becomes a full code execution primitive — injected scripts can exfiltrate cookies, keylog form inputs, or pivot to your users' other browser contexts. CSP is the browser-enforced last line of defense: even when input sanitization fails, a tight policy prevents injected scripts from loading external resources or executing inline. OWASP A03 (Injection) and A05 (Security Misconfiguration) both call out missing CSP as a critical gap; CWE-79 names the XSS class that a CSP directly mitigates. Without it, a single missed sanitization anywhere in your rendering pipeline becomes an account-takeover vector.

## Severity rationale

High because the absence of any CSP removes the last browser-enforced barrier against XSS exploitation, leaving injected scripts with unrestricted execution access.

## Remediation

Add a `Content-Security-Policy` header starting with a restrictive `default-src 'self'` and expand from there based on what your app actually loads. Start minimal and use browser console violation reports to tune.

```js
// next.config.js
headers: [{
  key: 'Content-Security-Policy',
  value: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'"
}]
```

If your app uses third-party scripts, add their domains explicitly (`script-src 'self' https://cdn.example.com`) rather than using the wildcard `*`. For inline scripts, use nonces rather than `unsafe-inline` — see the `csp-no-unsafe-inline` pattern for the nonce implementation.

## Detection

- **ID:** `csp-present`
- **Severity:** `high`
- **What to look for:** Count all locations where a Content-Security-Policy could be defined: framework config headers, middleware, deployment config, and `<meta http-equiv="Content-Security-Policy">` tags. A basic CSP that defines at least 1 directive (`default-src`) counts.
- **Pass criteria:** A CSP header or meta tag is present with at least 1 `default-src` directive that is not set to the wildcard value `*` alone. The directive must restrict sources to a defined set (e.g., `'self'`, specific domains, or nonce/hash patterns). A well-configured CSP typically defines at least 3 directives (e.g., `default-src`, `script-src`, `style-src`).
- **Fail criteria:** No CSP configuration found anywhere in the project, or CSP is present but `default-src` is set to `*` with no other restricting directives.
- **Do NOT pass when:** CSP is present but set to report-only mode (`Content-Security-Policy-Report-Only`) without an accompanying enforcement policy (`Content-Security-Policy`). Report-only without enforcement provides monitoring but no protection.
- **Skip (N/A) when:** Never — CSP is essential for any web project.
- **Cross-reference:** For XSS prevention beyond CSP, the Client-Side Framework Security audit covers DOM-based protections, sanitization, and safe rendering patterns.
- **Detail on fail:** `"No Content-Security-Policy header configured in next.config.js, middleware, or meta tags"`
- **Remediation:** CSP tells browsers what resources your page is allowed to load, preventing XSS and data injection attacks. Start with a basic policy:

  ```js
  // next.config.js
  headers: [{
    key: 'Content-Security-Policy',
    value: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'"
  }]
  ```

  Refine the policy based on your actual resource needs. Use browser console CSP violation reports to identify what to allow.

## External references

- cwe CWE-1021
- cwe CWE-79
- owasp A05
- owasp A03

Taxons: injection-and-input-trust

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