# Content-Security-Policy Header — Syntax, Values & Examples

> Restricts where a page may load scripts, styles, images and frames from — the main defence against cross-site scripting.

A CSP is an allow-list for your page. If an attacker manages to inject a `<script>` tag, the browser refuses to run it unless the policy allows its source. Modern policies use nonces or hashes rather than host lists, so only the scripts your server deliberately marked can run.

- Type: Response header
- Category: Security
- Defined in: [W3C — Content Security Policy Level 3](https://www.w3.org/TR/CSP3/)

## Syntax

```http
Content-Security-Policy: <directive> <source> <source>; <directive> …
```

## Values

| Value | Meaning |
|---|---|
| `default-src` | fallback for the other fetch directives |
| `script-src` | where scripts may come from ('self', nonces, hashes, hosts) |
| `style-src` | where stylesheets and inline styles may come from |
| `img-src` | where images may come from |
| `connect-src` | where fetch(), XHR and WebSockets may connect |
| `frame-ancestors` | which sites may embed this page in a frame |
| `object-src` | plugins; set to 'none' |
| `base-uri` | restricts the <base> element |
| `form-action` | where forms may submit |
| `report-to / report-uri` | where the browser reports violations |

## Examples

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

a strict starting point for a site that serves everything itself

```http
Content-Security-Policy: script-src 'nonce-r4nd0m' 'strict-dynamic'; object-src 'none'; base-uri 'none'
```

a nonce-based policy: only scripts carrying this response's nonce run

## Good to know

- Roll out with `Content-Security-Policy-Report-Only` first: violations are reported, nothing breaks.
- Avoid `'unsafe-inline'` for scripts — it undoes most of CSP's protection. Use nonces or hashes.
- A nonce must be random and new on every response; a fixed nonce protects nothing.
- `frame-ancestors 'none'` replaces `X-Frame-Options: DENY` in modern browsers.

## How to set Content-Security-Policy

### Express

```
res.set("Content-Security-Policy", "default-src 'self'; img-src 'self' data:; object-src 'none'; frame-ancestors 'none'");
```

### Next.js (next.config.js)

```
module.exports = {
  async headers() {
    return [
      {
        source: "/(.*)",
        headers: [{ key: "Content-Security-Policy", value: "default-src 'self'; img-src 'self' data:; object-src 'none'; frame-ancestors 'none'" }],
      },
    ];
  },
};
```

### nginx

```
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data:; object-src 'none'; frame-ancestors 'none'" always;
```

### Apache (.htaccess)

```
Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data:; object-src 'none'; frame-ancestors 'none'"
```

## Check it

Fetch only the response headers and filter for Content-Security-Policy. In the browser, it's under Response Headers in DevTools → Network.

```sh
curl -sI https://example.com/ | grep -i '^content-security-policy:'
```

## FAQ

### Why does my CSP break inline scripts and styles?

Inline code is blocked unless the policy allows it with a nonce, a hash, or 'unsafe-inline'. Move scripts into files, or add a per-response nonce to both the policy and the script tags.

### Can I set CSP in a meta tag?

Yes, with <meta http-equiv="Content-Security-Policy">, but frame-ancestors, report-uri and sandbox don't work there. Prefer the header.

## Related headers

- [X-Frame-Options](https://www.devkult.com/headers/x-frame-options.md): Controls whether the page may be shown inside a frame, protecting against clickjacking.
- [Strict-Transport-Security](https://www.devkult.com/headers/strict-transport-security.md): Tells browsers to use only HTTPS for the site for a set period, blocking downgrade attacks.
- [X-Content-Type-Options](https://www.devkult.com/headers/x-content-type-options.md): With nosniff, stops browsers guessing a response's type, so a text file can't be run as a script.

## Further reading

- [Content Security Policy guide](https://www.devkult.com/blog/content-security-policy-guide.md)
- [Security headers checklist](https://www.devkult.com/blog/security-headers-checklist.md)
- [Security headers generator](https://www.devkult.com/tools/security/security-headers-generator.md)

Open the interactive page: https://www.devkult.com/headers/content-security-policy