# Restrictive default-src

- **Pattern:** `ab-002423` (`security-headers-ii.csp-quality.restrictive-default-src`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002423
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002423)

## Why it matters

A permissive or missing `default-src` directive means every resource type without an explicit CSP directive — fonts, media, frames, workers, manifests — defaults to unrestricted loading. An attacker who achieves any injection can load arbitrary resources from any origin using these unguarded resource types, side-stepping the protections you applied to `script-src`. CWE-79 and CWE-693 both apply here. OWASP A03 identifies missing fallback directives as a common CSP misconfiguration that leaves partial protection in place while creating exploitable gaps in less-obvious resource categories.

## Severity rationale

High because a permissive `default-src` creates exploitable gaps in every resource type that lacks an explicit directive, undermining the intent of the entire CSP policy.

## Remediation

Set `default-src` to `'none'` or `'self'` as the first directive, then add specific source directives only for resource types your application actually uses.

```
# Start from none and add specific overrides
Content-Security-Policy:
  default-src 'none';
  script-src 'self' 'nonce-{perRequest}' 'strict-dynamic';
  style-src 'self';
  img-src 'self' data:;
  font-src 'self';
  connect-src 'self' https://api.yourdomain.com;
  frame-ancestors 'none'
```

Prefer `'none'` for maximum restriction — add back only the categories your app needs. This approach forces you to be explicit about every resource type rather than inheriting broad defaults.

## Detection

- **ID:** `restrictive-default-src`
- **Severity:** `high`
- **What to look for:** Parse the CSP header and extract the `default-src` directive. This is the fallback for any resource type not explicitly specified (script-src, style-src, img-src, etc.). If `default-src` is missing, permissive (`*`, `data:`, `https:`), or overly broad, unspecified resource types have no protection.
- **Pass criteria:** `default-src` is set to exactly `'self'` or `'none'` — no more than 1 source allowed. Count all sources in default-src and quote the actual default-src value even on pass: "default-src is set to 'self'."
- **Fail criteria:** `default-src` is missing, set to `*`, `data:`, `https:`, or includes overly broad sources.
- **Report even on pass:** Always quote the actual `default-src` value. Example: "default-src is set to 'self'."
- **Skip (N/A) when:** No Content-Security-Policy header configured. Run Security Headers & Basics first.
- **Detail on fail:** `"default-src is set to 'https:' — any HTTPS source is allowed as fallback for unspecified directives"` or `"No default-src directive found — browser defaults to * for unspecified resource types"`
- **Remediation:** `default-src` is the most important CSP directive — it provides the fallback policy for any resource type you haven't explicitly configured:

  ```
  # Start restrictive, then add specific directives as needed
  default-src 'none'; script-src 'nonce-abc123' 'strict-dynamic'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'
  ```

  `'none'` is the strictest option — it blocks everything not explicitly allowed by another directive. `'self'` is a good starting point that allows same-origin resources.

## External references

- cwe CWE-79
- cwe CWE-693
- owasp A03

Taxons: injection-and-input-trust

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