A public website often has many attack surfaces:
And many others.
XSS attacks exploit the browser’s trust in the content received from the server. Since the browser trusts the source of the content, malicious scripts are also executed by the user’s browser by default. Even if these scripts do not come from where they appear to come from.
The goal of the CSP is, among other things, to detect and prevent such XSS attacks. This is done by the web server sending a header with information about which files and data are safe for which sources. A header is the part of a request and response that is always sent first. For example, the browser usually sends the accepted languages in the header, which the user understands.
There is an intermediate solution for this. So instead of setting the header right away a Report-Only header is set. Now it can be read in the browser console or with a script on the server where it hangs. To do this, the entire website must be combed through. This can be done with automated tools or manually if there are only a few pages to be tested. Alternatively or additionally, if that’s the main focus as in this example, you can also look for telltale inline scripts. If you are running the website as a container or can otherwise test it offline or on a test system (for example, in the case of a primarily static site), testing there would be preferable.
Unless you and the website owner have a good sense of humor.
Detecting inline scripts in a Hugo template:
find themes -name "*.html" -print0 | xargs -0 grep "<script>"
A CSP violation may look like this in the browser console, for example:
Content Security Policy: The page settings have blocked loading a resource on inline ("script-src"). www.example.de
Content Security Policy: The page settings have blocked loading a resource on inline ("script-src"). www.example.de:9:1
Content Security Policy: The page settings have blocked loading a resource on data:image/svg+xml,%3Csvg xmlns=%22http:... ("img-src").
Content Security Policy: The page settings have blocked loading a resource on data:image/svg+xml,%3csvg xmlns='http://... ("img-src").
An output on the server (well, via the user’s browser, though) might look like this, for example:
{
"csp-report":{
"blocked-uri": "inline",
"column-number":1,
"document-uri": "https://www.example.com/",
"line-number":9,
"original-policy": "default-src 'self' https://*.example.com https://*.example.de; img-src *; media-src *; script-src https://*.example.com https://*.example.de; report-uri https://www.example.com/csp-report.php",
"referrer":"",
"source-file": "https://www.example.com/",
"violated-directive": "script-src"
}
}
content-security-policy "default-src 'self' *.example.com *.example.de; img-src *; media-src *; script-src *.example.com *.example.de"
Content-Security-Policy-Report-Only "default-src 'self' *.example.com *.example.de; img-src *; media-src *; script-src *.example.com *.example.de; report-uri /csp-reporter.php"