# Headers (/en/docs/web-security/policies/content-security-policy/introduction/csp-headers)



A Content Security Policy (CSP) reaches the browser as an HTTP response header.
You send the policy on the response, the browser reads it, and from that point it
applies the rules to the page. This page covers the two delivery headers, how the
policy reports violations, the limits of `<meta>` delivery, and what happens when
a response carries more than one policy.

For the policy contents themselves, see the
[directives](/en/docs/web-security/policies/content-security-policy/introduction/csp-directives)
and the
[values](/en/docs/web-security/policies/content-security-policy/introduction/csp-values)
they accept.

The enforcing header in its simplest form:

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

## Enforce vs report-only [#enforce-vs-report-only]

There are two headers that deliver a policy. They take the exact same syntax; the
only difference is what the browser does with a violation.

| Header                                                                                                    | Status | What the browser does                                     |
| --------------------------------------------------------------------------------------------------------- | ------ | --------------------------------------------------------- |
| `Content-Security-Policy`                                                                                 | ✅ Good | Enforces the policy: blocks the violation and reports it. |
| [Content-Security-Policy-Report-Only](/en/docs/web-security/policies/content-security-policy/report-only) | ✅ Good | Reports the violation but does not block it.              |

Report-only mode lets you watch what a policy would break before you turn it on.
You deploy the policy on the report-only header, collect the reports, fix what
the policy would have blocked, then move the same string to the enforcing header.
A report-only policy needs a reporting endpoint to be useful, since reporting is
all it does.

```http
Content-Security-Policy-Report-Only:
  default-src 'self';
  report-to csp-endpoint
```

A response can carry both an enforcing policy and a report-only policy at once,
which lets you enforce a known-good baseline while testing a stricter policy in
parallel.

## How the policy reports [#how-the-policy-reports]

A policy points the browser at an endpoint with one of two directives.

* `report-to` names a reporting group. The group's URL lives in a separate
  [Reporting-Endpoints](/en/docs/web-security/reporting-api/headers/reporting-endpoints)
  header, part of the Reporting API. This is the current mechanism. See the CSP
  [report-to](/en/docs/web-security/policies/content-security-policy/directives/report-to)
  page.
* `report-uri` posts reports straight to a URL. It is the legacy mechanism and is
  ignored where `report-to` is supported, which is now every current browser
  (Chrome, Edge, Safari, and Firefox).

`report-to` is the primary mechanism; keep `report-uri` alongside it only to
cover old, unupdated browser versions. The modern `Reporting-Endpoints` header
pairs with `report-to`; the older
[Report-To](/en/docs/web-security/reporting-api/headers/report-to) header is a separate,
deprecated mechanism that CSP no longer needs (it remains required only for NEL).

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

```http
Content-Security-Policy:
  default-src 'self';
  report-uri https://<Endpoint-ID>.report.centralcsp.com;
  report-to csp-endpoint
```

The two delivery paths produce different report shapes: hyphenated field names
for `report-uri` and camelCase for `report-to`. Both land as a
[CSP violation report](/en/docs/web-security/reporting-api/reports/csp-violation), which
CentralCSP collects and normalizes. To confirm your endpoint is wired correctly,
run the [Reporting API checker](/tools/reporting-api).

## Delivery through a meta tag [#delivery-through-a-meta-tag]

You can also deliver a policy in HTML with a `<meta>` tag in the document
`<head>`, which is useful when you cannot set response headers.

```html
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; object-src 'none'">
```

A `<meta>` policy is more limited than a header. It cannot do report-only. It
cannot use `report-uri`, `report-to`, `frame-ancestors`, or `sandbox`. It must
appear in the `<head>`, and it only governs content that comes after it in the
document. Prefer the HTTP header where you can set one.

## How multiple policies combine [#how-multiple-policies-combine]

When a response carries more than one enforcing policy, the browser applies all
of them, and a resource must satisfy every one to load. Policies combine by
intersection, so the effective rule is the most restrictive across all of them.

This means adding a policy can only ever tighten the result, never loosen it. A
second policy of `script-src 'self'` will not re-allow a host that a first policy
of `script-src 'none'` already blocked. Each policy is also evaluated
independently for reporting, so one violation can produce reports to several
endpoints.

## Recommendation [#recommendation]

Run both headers together: enforce the policy you trust today, and test each
tightening step in a report-only policy before promoting it. Wire reporting
through `report-to` and
[Reporting-Endpoints](/en/docs/web-security/reporting-api/headers/reporting-endpoints),
which every current browser now supports.

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

```http
Content-Security-Policy:
    script-src 'nonce-{RANDOM}' 'strict-dynamic';
    object-src 'none';
    base-uri 'none';
    report-to csp-endpoint
```

```http
Content-Security-Policy-Report-Only:
    script-src 'nonce-{RANDOM}' 'strict-dynamic';
    connect-src 'self';
    report-to csp-endpoint
```

Staged tightening with a report-only shadow policy is how the
[web.dev strict CSP guide](https://web.dev/articles/strict-csp) recommends
rolling a policy out, and it keeps a production incident out of every change.

## FAQ [#faq]

### What is the difference between enforce and report-only CSP? [#what-is-the-difference-between-enforce-and-report-only-csp]

`Content-Security-Policy` blocks a violation and reports it;
`Content-Security-Policy-Report-Only` only reports it, so you can test a policy
before enforcing. See [enforce vs report-only](/en/blog/csp-enforce-vs-report-only)
for the full rollout workflow.

### Can I set a CSP in a meta tag? [#can-i-set-a-csp-in-a-meta-tag]

Yes for most directives, but a `<meta http-equiv="Content-Security-Policy">` tag
cannot do report-only and ignores `report-uri`, `report-to`, `frame-ancestors`,
and `sandbox`. See [meta tags vs headers](/en/blog/csp-meta-tags-vs-headers) for
when to use each.

## See also [#see-also]

* [What is CSP](/en/docs/web-security/policies/content-security-policy/introduction/what-is-csp)
* [Content-Security-Policy-Report-Only](/en/docs/web-security/policies/content-security-policy/report-only)
* [report-to directive](/en/docs/web-security/policies/content-security-policy/directives/report-to)
* [Reporting-Endpoints](/en/docs/web-security/reporting-api/headers/reporting-endpoints)
* [X-Frame-Options](/en/docs/web-security/security-headers/x-frame-options)
* [CSP violation report](/en/docs/web-security/reporting-api/reports/csp-violation)

## Sources [#sources]

* [MDN, Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy)
* [W3C, Content Security Policy Level 3](https://www.w3.org/TR/CSP3/)
* [web.dev, Mitigate cross-site scripting with a strict CSP](https://web.dev/articles/strict-csp)
