# default-src (/en/docs/web-security/policies/content-security-policy/directives/default-src)



The `default-src` directive is the fallback source list for most fetch directives in a Content Security Policy (CSP). Any fetch directive you do not set explicitly inherits the sources you give `default-src`, so it is the safety net that decides what loads when a more specific rule is absent.

A minimal safe policy for this directive:

```http
Content-Security-Policy: default-src 'self'
```

## Fallback chain [#fallback-chain]

`default-src` itself has no fallback. It is the bottom of the chain: when the browser checks a resource, it looks for the most specific directive first, and only falls back to `default-src` if that directive is not present in the policy.

Setting `default-src 'self'` does not mean every directive is now `'self'`. It means every fetch directive you omit behaves as `'self'`. The moment you add a specific directive, for example [`script-src`](/en/docs/web-security/policies/content-security-policy/directives/script-src), that directive takes over for scripts and `default-src` no longer applies to them. A common mistake is setting `script-src` and assuming images are still covered: they are, but only through `default-src`, so you have to keep `default-src` in place or name [`img-src`](/en/docs/web-security/policies/content-security-policy/directives/img-src) too.

The directives `default-src` backs include [`script-src`](/en/docs/web-security/policies/content-security-policy/directives/script-src), [`style-src`](/en/docs/web-security/policies/content-security-policy/directives/style-src), [`img-src`](/en/docs/web-security/policies/content-security-policy/directives/img-src), [`font-src`](/en/docs/web-security/policies/content-security-policy/directives/font-src), [`connect-src`](/en/docs/web-security/policies/content-security-policy/directives/connect-src), [`media-src`](/en/docs/web-security/policies/content-security-policy/directives/media-src), [`object-src`](/en/docs/web-security/policies/content-security-policy/directives/object-src), [`manifest-src`](/en/docs/web-security/policies/content-security-policy/directives/manifest-src), and [`worker-src`](/en/docs/web-security/policies/content-security-policy/directives/worker-src) (through [`child-src`](/en/docs/web-security/policies/content-security-policy/directives/child-src)).

A fetch resolves to its own directive when that directive is present, and falls back to `default-src` only when it is absent:

```mermaid
flowchart LR
  A["Image request"] --> B{"img-src set?"}
  B -->|"yes"| C["Use img-src"]
  B -->|"no"| D["Fall back to default-src"]
```

The document and navigation directives do not take part in this chain. `base-uri`, `form-action`, `frame-ancestors`, `sandbox`, and the reporting directives never fall back to `default-src`, so an unset one of these stays unset.

### What default-src does not cover [#what-default-src-does-not-cover]

This is the most common CSP misunderstanding. `default-src` is only a fallback for the *fetch* directives. It does not cover the document and navigation directives:

* [`base-uri`](/en/docs/web-security/policies/content-security-policy/directives/base-uri)
* [`form-action`](/en/docs/web-security/policies/content-security-policy/directives/form-action)
* [`frame-ancestors`](/en/docs/web-security/policies/content-security-policy/directives/frame-ancestors)
* [`sandbox`](/en/docs/web-security/policies/content-security-policy/directives/sandbox)
* The reporting directives [`report-uri`](/en/docs/web-security/policies/content-security-policy/directives/report-uri) and [`report-to`](/en/docs/web-security/policies/content-security-policy/directives/report-to)

If you want to restrict where forms post or which sites may frame your page, you have to set those directives yourself. `default-src 'self'` does nothing for them. Leaving `base-uri` unset, for example, is a real cross-site scripting vector even with a tight `default-src`.

## Values [#values]

`default-src` takes a space-separated source list, the same grammar every fetch directive uses. Because it is the fallback for the fetch directives, it accepts everything `script-src` does; the script-only keywords take effect when the fallback ends up governing a script check.

| Value                                                     | Status          | Description                                                                                                                                |
| --------------------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `'none'`                                                  | ✅ Good          | Blocks every fetch the policy governs. Used alone.                                                                                         |
| `'self'`                                                  | ✅ Good          | Resources from your own origin only.                                                                                                       |
| Host source                                               | ✅ Good          | A specific host such as `cdn.example.com`.                                                                                                 |
| `https:`                                                  | ❌ Risky         | Any origin over TLS, including for scripts through the fallback.                                                                           |
| `data:`                                                   | ❌ Risky         | Executes as script through the fallback. Allow it on `img-src` or `font-src` instead.                                                      |
| `blob:`                                                   | ❌ Risky         | `blob:` URLs execute as script through the fallback.                                                                                       |
| `'nonce-...'`                                             | ✅ Good          | Per-response random token; only meaningful for scripts and styles.                                                                         |
| `'sha256-...'`                                            | ✅ Good          | Digest of an exact inline block; only meaningful for scripts and styles.                                                                   |
| `'strict-dynamic'`                                        | ✅ Good          | Applies when the fallback governs scripts; host and scheme sources are then ignored.                                                       |
| `'wasm-unsafe-eval'`                                      | ✅ Good          | WebAssembly compilation only, narrower than `'unsafe-eval'`.                                                                               |
| `'report-sample'`                                         | ✅ Good          | Adds the first 40 characters of blocked inline content to reports.                                                                         |
| `'trusted-types-eval'`                                    | ✅ Good          | Allows eval only with TrustedScript when Trusted Types are enforced. Recently became available across current Chrome, Firefox, and Safari. |
| `'unsafe-inline'`                                         | ❌ Risky         | Allows every inline script and style, including injected ones.                                                                             |
| `'unsafe-eval'`                                           | ❌ Risky         | Allows `eval()`, `new Function()`, and string timers.                                                                                      |
| `'unsafe-hashes'`                                         | ❌ Risky         | Lets hashes match inline event handlers, re-enabling that surface.                                                                         |
| `'inline-speculation-rules'`                              | 🧪 Experimental | Inline speculation rules scripts. Chromium-led, not on the standards track.                                                                |
| `'report-sha256'` / `'report-sha384'` / `'report-sha512'` | 🧪 Experimental | [Report-only hash collection](/en/docs/web-security/policies/content-security-policy/values/report-sha-keyword). Chromium-only.            |

You can combine:

* the [keyword sources](/en/docs/web-security/policies/content-security-policy/values/csp-keywords) such as `'self'` and `'none'`
* a [host source](/en/docs/web-security/policies/content-security-policy/values/csp-host-source) such as `cdn.example.com` or `*.example.com`
* a [scheme source](/en/docs/web-security/policies/content-security-policy/values/csp-scheme-source) such as `https:`
* a [nonce or hash](/en/docs/web-security/policies/content-security-policy/values/csp-hashes-nonce) source, though these only make sense for scripts and styles

`default-src 'none'` blocks every fetch the policy governs, which is a strict baseline you then open up directive by directive.

## Examples [#examples]

```http
Content-Security-Policy:
  default-src 'self';
  img-src 'self' data:;
  object-src 'none'
```

Here scripts, styles, fonts, media, and connections all fall back to `'self'`. Images additionally allow `data:` URIs, and plugins are blocked outright. Anything not named inherits `'self'` from `default-src`.

## Security notes [#security-notes]

`default-src 'self'` is a reasonable floor, but on its own it still allows same-origin inline scripts to be loaded as external files and does nothing for the document directives above. For a strong policy, set `default-src` as the catch-all, then tighten the high-risk directives explicitly: a nonce or hash plus `'strict-dynamic'` on [`script-src`](/en/docs/web-security/policies/content-security-policy/directives/script-src), `object-src 'none'`, and `base-uri 'none'`. You can check a draft policy for gaps with the [CSP evaluator](/tools/csp-evaluator) before you ship it.

Avoid `default-src *` or a wildcard scheme like `default-src https:`, which allows loading from any host and gives almost no protection. A bare `*` does not match `data:`, `blob:`, or `filesystem:`, so a wildcard is both too broad and quietly incomplete.

## Known bypasses and risks [#known-bypasses-and-risks]

The real risk with `default-src` is over-trusting it. Because it does not cover `base-uri`, `form-action`, `frame-ancestors`, or `sandbox`, a policy of `default-src 'self'` alone leaves clickjacking, base-tag injection, and form-action exfiltration open. Set those directives directly.

If you rely on `default-src` to cover scripts but the page needs an inline script, you cannot loosen scripts without loosening everything, since `default-src 'unsafe-inline'` weakens every fetch type. Add an explicit [`script-src`](/en/docs/web-security/policies/content-security-policy/directives/script-src) instead, so the relaxation is scoped to scripts.

## Recommendation [#recommendation]

Start from `default-src 'self'` as the catch-all, set the directives that never fall back explicitly, and tighten scripts with their own directive, inside a complete base policy:

```http
Content-Security-Policy:
    default-src 'self';
    script-src 'nonce-{RANDOM}' 'strict-dynamic';
    style-src 'self';
    img-src 'self';
    font-src 'self';
    connect-src 'self';
    media-src 'self';
    manifest-src 'self';
    frame-src 'none';
    worker-src 'self';
    object-src 'none';
    base-uri 'none';
    form-action 'self';
    frame-ancestors 'none';
    upgrade-insecure-requests;
    report-to csp-endpoint
```

Pair it with the endpoint declaration in a separate block:

```http
Reporting-Endpoints: csp-endpoint="https://<Endpoint-ID>.report.centralcsp.com"
```

`default-src 'self'` covers every fetch you did not name, while `base-uri`, `form-action`, and `frame-ancestors` are set directly because the fallback never reaches them. Script handling moves to `script-src`, so you can adopt a nonce without loosening the rest of the policy.

## Reporting [#reporting]

When a request is blocked through the `default-src` fallback, the browser sends a [csp-violation report](/en/docs/web-security/reporting-api/reports/csp-violation) naming the effective directive that was checked. Point the policy at a reporting endpoint to collect these and see which fetch types the fallback is catching before you tighten it.

## Browser support [#browser-support]

`default-src` is part of CSP Level 1 and is supported in every browser that implements CSP. It is stable and widely available.

## FAQ [#faq]

### Does default-src cover every directive? [#does-default-src-cover-every-directive]

No. `default-src` is a fallback only for the fetch directives. It does not cover `base-uri`, `form-action`, `frame-ancestors`, `sandbox`, or the reporting directives, which stay unset unless you name them explicitly. A tight `default-src 'self'` does nothing for those, so set them yourself.

### Is default-src 'self' enough for a CSP? [#is-default-src-self-enough-for-a-csp]

No. `default-src 'self'` is a reasonable floor, but on its own it allows same-origin inline scripts and does nothing for the document directives. For a strong policy, add a nonce or hash plus `'strict-dynamic'` on `script-src`, `object-src 'none'`, and `base-uri 'none'`.

## See also [#see-also]

* [Content Security Policy directives](/en/docs/web-security/policies/content-security-policy/introduction/csp-directives)
* [script-src](/en/docs/web-security/policies/content-security-policy/directives/script-src)
* [base-uri](/en/docs/web-security/policies/content-security-policy/directives/base-uri)
* [CSP keyword values](/en/docs/web-security/policies/content-security-policy/values/csp-keywords)
* [CentralCSP CSP suite](/platform/csp-builder)

## Sources [#sources]

* [MDN, CSP default-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/default-src)
* [W3C, Content Security Policy Level 3](https://www.w3.org/TR/CSP3/)
* [W3C CSP editor's draft](https://w3c.github.io/webappsec-csp/)
