Revision 1141699 of Content-Security-Policy-Report-Only

  • Revision slug: Web/HTTP/Headers/Content-Security-Policy-Report-Only
  • Revision title: Content-Security-Policy-Report-Only
  • Revision id: 1141699
  • Created:
  • Creator: fscholz
  • Is current revision? No
  • Comment new page

Revision Content

{{HTTPSidebar}}

The HTTP Content-Security-Policy-Report-Only response header allows web developers to experiment with policies by monitoring (but not enforcing) their effects. These violation reports consist of {{Glossary("JSON")}} documents sent via an HTTP POST request to the specified URI.

Header type {{Glossary("Response header")}}
{{Glossary("Forbidden header name")}} no
This header is not supported inside a {{HTMLElement("meta")}} element.

Syntax

Content-Security-Policy-Report-Only: <policy-directive>; <policy-directive>

Directives

The same directives the {{HTTPHeader("Content-Security-Header")}} uses can be applied to Content-Security-Policy-Report-Only.

Examples

This header reports violations that would have occured. You can use this to iteratively work on your content security policy. You observe how your site behaves, watching for violation reports, then choose the desired policy enforced by the {{HTTPHeader("Content-Security-Header")}}.

Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-violation-report-endpoint/

If you still want to receive reporting, but also want to enforce a policy, use the {{HTTPHeader("Content-Security-Header")}} with the {{CSP("report-uri")}} directive.

Content-Security-Policy: default-src https:; report-uri /csp-violation-report-endpoint/

Violation report syntax

The report JSON object contains the following data:

document-uri
The URI of the document in which the violation occurred.
referrer
The referrer of the document in which the violation occurred.
blocked-uri
The URI of the resource that was blocked from loading by the Content Security Policy. If the blocked URI is from a different origin than the document-uri, then the blocked URI is truncated to contain just the scheme, host, and port.
violated-directive
The name of the policy section that was violated.
original-policy
The original policy as specified by the Content-Security-Policy HTTP header.
disposition
Either "enforce" or "reporting" depending on whether the {{HTTPHeader("Content-Security-Header")}} or the Content-Security-Header-Report-Only header is used.

Sample violation report

Let's consider a page located at http://example.com/signup.html. It uses the following policy, disallowing everything but stylesheets from cdn.example.com.
Content-Security-Policy-Report-Only: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports
The HTML of signup.html looks like this:
<!DOCTYPE html>
<html>
  <head>
    <title>Sign Up</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    ... Content ...
  </body>
</html>
Can you spot the violation? Stylesheets are only allowed to be loaded from cdn.example.com, yet the website tries to load one from its own origin (http://example.com). A browser capable of enforcing CSP will send the following violation report as a POST request to http://example.com/_/csp-reports, when the document is visited:
{
  "csp-report": {
    "document-uri": "http://example.com/signup.html",
    "referrer": "",
    "blocked-uri": "http://example.com/css/style.css",
    "violated-directive": "style-src cdn.example.com",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports",
    "disposition": "report"
  }
}

As you can see, the report includes the full path to the violating resource in blocked-uri. This is not always the case. For example, when the signup.html would attempt to load CSS from http://anothercdn.example.com/stylesheet.css, the browser would not include the full path but only the origin (http://anothercdn.example.com). This is done to prevent leaking sensitive information about cross-origin resources.

Specifications

Specification Status Comment
{{specName("CSP 3.0")}} {{Spec2('CSP 3.0')}} No changes.
{{specName("CSP 1.1")}} {{Spec2('CSP 1.1')}} Initial definition.

Browser compatibility

{{Compat}}

See also

Revision Source

<div>{{HTTPSidebar}}</div>

<p>The HTTP <strong><code>Content-Security-Policy-Report-Only</code></strong> response header allows web developers to experiment with policies by monitoring (but not enforcing) their effects. These violation reports consist of {{Glossary("JSON")}} documents sent via an HTTP <code>POST</code> request to the specified URI.</p>

<table class="properties">
 <tbody>
  <tr>
   <th scope="row">Header type</th>
   <td>{{Glossary("Response header")}}</td>
  </tr>
  <tr>
   <th scope="row">{{Glossary("Forbidden header name")}}</th>
   <td>no</td>
  </tr>
  <tr>
   <th colspan="2" scope="row">This header is not supported inside a {{HTMLElement("meta")}} element.</th>
  </tr>
 </tbody>
</table>

<h2 id="Syntax">Syntax</h2>

<pre class="syntaxbox">
Content-Security-Policy-Report-Only: &lt;policy-directive&gt;; &lt;policy-directive&gt;
</pre>

<h2 id="Directives">Directives</h2>

<p>The same directives the {{HTTPHeader("Content-Security-Header")}} uses can be applied to <code>Content-Security-Policy-Report-Only</code>.</p>

<h2 id="Examples">Examples</h2>

<p>This header reports violations that would have occured. You can use this to iteratively work on your content security policy. You observe how your site behaves, watching for violation reports, then choose the desired policy enforced by the {{HTTPHeader("Content-Security-Header")}}.</p>

<pre>
Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-violation-report-endpoint/</pre>

<p>If you still want to receive reporting, but also want to enforce a policy, use the {{HTTPHeader("Content-Security-Header")}} with the {{CSP("report-uri")}} directive.</p>

<pre>
Content-Security-Policy: default-src https:; report-uri /csp-violation-report-endpoint/</pre>

<h2 id="Violation_report_syntax">Violation report syntax</h2>

<p>The report JSON&nbsp;object contains the following data:</p>

<dl>
 <dt><code>document-uri</code></dt>
 <dd>The URI of the document in which the violation occurred.</dd>
 <dt><code>referrer</code></dt>
 <dd>The referrer of the document in which the violation occurred.</dd>
 <dt><code>blocked-uri</code></dt>
 <dd>The URI&nbsp;of the resource that was blocked from loading by the Content Security Policy. If the blocked URI is from a different origin than the document-uri, then the blocked URI is truncated to contain just the scheme, host, and port.</dd>
 <dt><code>violated-directive</code></dt>
 <dd>The name of the policy section that was violated.</dd>
 <dt><code>original-policy</code></dt>
 <dd>The original policy as specified by the <code>Content-Security-Policy</code> HTTP header.</dd>
 <dt>disposition</dt>
 <dd>Either "enforce" or "reporting" depending on whether the {{HTTPHeader("Content-Security-Header")}} or the <code>Content-Security-Header-Report-Only</code> header is used.</dd>
</dl>

<h2 id="Sample_violation_report">Sample violation report</h2>

<div>Let's consider a page located at&nbsp;<code>http://example.com/signup.html</code>. It uses the following policy, disallowing everything but stylesheets from <code>cdn.example.com</code>.</div>

<div>
<pre>
Content-Security-Policy-Report-Only: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports</pre>
</div>

<div>The HTML of <code>signup.html</code> looks like this:</div>

<pre class="brush: html">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Sign Up&lt;/title&gt;
    &lt;link rel="stylesheet" href="css/style.css"&gt;
  &lt;/head&gt;
  &lt;body&gt;
    ... Content ...
  &lt;/body&gt;
&lt;/html&gt;</pre>

<div>Can you spot the violation? Stylesheets are only allowed to be loaded from <code>cdn.example.com</code>, yet the website tries to load one from its own origin (<code>http://example.com</code>). A browser capable of enforcing CSP will send the following violation report as a POST request to&nbsp;<code>http://example.com/_/csp-reports</code>, when&nbsp;the document is visited:</div>

<pre>
{
  "csp-report": {
    "document-uri": "http://example.com/signup.html",
    "referrer": "",
    "blocked-uri": "http://example.com/css/style.css",
    "violated-directive": "style-src cdn.example.com",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports",
    "disposition": "report"
  }
}</pre>

<p>As you can see, the report includes the full path to the violating resource in <code>blocked-uri</code>. This is not always the case. For example, when the <code>signup.html</code> would attempt to load CSS from <code>http://anothercdn.example.com/stylesheet.css</code>, the browser would <em>not</em> include the full path but only the origin (<code>http://anothercdn.example.com</code>). This is done to prevent leaking sensitive information about cross-origin resources.</p>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{specName("CSP 3.0")}}</td>
   <td>{{Spec2('CSP 3.0')}}</td>
   <td>No changes.</td>
  </tr>
  <tr>
   <td>{{specName("CSP 1.1")}}</td>
   <td>{{Spec2('CSP 1.1')}}</td>
   <td>Initial definition.</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Browser compatibility</h2>

<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>

<p>{{Compat}}</p>

<h2 id="See_also">See also</h2>

<ul>
 <li>{{HTTPHeader("Content-Security-Policy")}}</li>
 <li>CSP {{CSP("report-uri")}} directive</li>
 <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy">Content Security in WebExtensions</a></li>
 <li>
  <p><a href="/en-US/docs/Tools/GCLI/Display_security_and_privacy_policies">Display security and privacy policies In Firefox Developer Tools</a></p>
 </li>
</ul>
Revert to this revision