Tell the browser where to send policy reports
A browser can send reports to you when something out-of-the-ordinary happens while visitors access your website.
Browsers send out-of-band reports (when properly configured by you) about problems encountered by visitors to your website. This is an important mechanism, allowing you to monitor the health of your website from the outside looking in. It is the complement to server-side logging and error reporting.
As of this writing (2019), this is an experimental technology, governed by a working draft specification.
You set this up by sending the browser a
report-to header — with one or more named report groups — instructing it where to send violation and network error reports. The
report-to header should be sent together with a
content-security-policy header or a
network-error-logging header, which in turn should reference the report group you set up.
Upon receipt, the browser will record and begin to use the specified instructions for all subsequent violations and errors for all documents coming from your website's domain (protocol + hostname + port). The browser will continue to do this, for the period of time that you specify in the
max-age portion of the header.
report-to header specifies an endpoint that is responsible for accepting and processing the reports sent to it by the browser. The endpoint is specified as a URL having a protocol, hostname, and resource path.
The endpoint may be hosted on the same web server as your website, but this is generally not wise. While security violation reports will successfully be reported to such an endpoint, network errors almost certainly will not. To ensure proper delivery of browser reports, it is safer to place the receiving endpoint on a different target hostname.
Following this advice though, leads to a fresh problem. CORS. In order for the browser to successfully send a report about your website to a different hostname, you must configure your website to allow cross origin resource sharing.
In order for the browser to successfully initiate a report from your site, it must receive a valid set of CORS headers. For example, a successful CORS configuration for a report endpoint hosted at
https://server-monitor.tld for a website at
https://domain.tld will need to respond to the browser's preflight OPTIONS request with these three response headers:
When the browser receives CORS permission to proceed, it will send reports using an HTTP
POST method with a content type of
application/reports+json. The endpoint should accept the
POST data, process it, and respond to the browser with status code
204 (No Content).
report-to section is configured subordinate to the
policies section. It contains one or more named report groups, each comprising two required settings, and one optional setting.
The required settings are:
endpointwhich is a URL, plus optional priority and weight attributes.
max-agewhich is the length of time (in seconds) that the browser should keep using this endpoint.
The optional setting is:
include-subdomainswhich will instruct the browser to also send reports to the specified endpoint for any subdomains of your website.
It is also possible to specify more than one endpoint for a single named group. To do this configure the section using an
endpoints (plural) subsection, and list the URL, priority, and weight for each one, on a separate line.
|group-name||::=||(ALPHA | DIGIT | HYPHEN)*|
|protocol||::=||'https://' | 'http://'|
|hostname||::=||(ALPHA | DIGIT | FULL-STOP | HYPHEN)*|
|endpoint-url||::=||protocol hostname SOLIDUS resource-path|
|priority-spec||::=||ASTERISK 'priority' EQUALS-SIGN DIGITS*|
|weight-spec||::=||ASTERISK 'weight' EQUALS-SIGN DIGITS*|
|endpoint-spec||::=||endpoint-url SP priority-spec SP weight-spec|
|endpoint||::=||'endpoint' SP endpoint-spec CR|
|endpoints||::=||'endpoints' SP LEFT-CURLY-BRACKET CR |
|max-age||::=||'max-age' SP DIGIT* CR|
|report-group||::=||'default' | group name SP LEFT-CURLY-BRACKET CR endpoint | endpoints | max-age | include-subdomains RIGHT-CURLY-BRACKET CR|
|policy-configs||::=||referrer-policy† | content-security-policy† | feature-policy† | network-error-logging† | report-to|
|policies-section||::=||'policies' SP LEFT-CURLY-BRACKET CR |
† These are defined in separate notes
Example 1: reporting security violations to origin server
`/csp-notifications` *methods=POST *plugin=rwserve-policy-reports
Example 2: reporting errors to endpoint on separate domain
The server to be monitored is configured with:
The server to receive browser-generated error reports is configured with:
`/nel-notifications` *origin="domain.tld" *headers=content-type *methods=POST
`/nel-notifications` *methods=POST *plugin=rwserve-policy-reports
Example 3: receiving deprecation and intervention reports
`/default-notifications` *methods=POST *plugin=rwserve-policy-reports
Key points to remember:
- The policies module must be on to enable
report-toresponse header is only sent when an HTML document is requested.
defaultgroup is used for deprecation and intervention reports.
- CORS must be configured when the
report-toendpoint is on a different host.