One helpful feature of Content Security Policy is ability to detect violations and sending it to specific URI as (Violation Report). According to documentation from CSP 1.1 Sec. 3.2.4 Reporting:
To send violation reports, the user agent must use an algorithm equivalent to the following:
- Fetch report URI from the origin of the protected resource, with the synchronous flag not set, using HTTP method POST, with a Content-Type header field of application/json with an entity body consisting of report body. If the origin of report URI is not the same as the origin of the protected resource, the block cookies flag must also be set. The user agent must not follow redirects when fetching this resource. (Note: The user agent ignores the fetched resource.)
Then, in section 5.2 Sample Violation Report provided an example:
In the following example, the user agent rendered a representation of the resource http://example.org/page.html with the following CSP policy:
default-src 'self'; report-uri http://example.org/csp-report.cgi
The protected resource loaded an image from http://evil.example.com/image.png, violating the policy.
{
"csp-report": {
"document-uri": "http://example.org/page.html",
"referrer": "http://evil.example.com/haxor.html",
"blocked-uri": "http://evil.example.com/image.png",
"violated-directive": "default-src 'self'",
"effective-directive": "img-src",
"original-policy": "default-src 'self'; report-uri http://example.org/csp-report.cgi"
}
}
Example:
test.php
<?php
header("X-Content-Security-Policy: default-src 'self'; report-uri http://127.0.0.1/csp-report.php");
?>
<img src="http://evil.example.com/image.png">
csp-report.php
<?php
$content = "
Keys: ".implode("\n", array_keys($_POST))."\n
\n--------------------------\n\n
Values: ".implode("\n", $_POST)."\n
";
file_put_contents('csp-report.txt', $content, FILE_APPEND | LOCK_EX);
?>
csp-report.txt
Keys:
--------------------------
Values:
As you see, nothing saved in that file! However, using Firebug, it seems that the report sent to that file:
Note: I expect analytical answer mentioning why normal post not working and what alternative should be used, and why? also, providing how to decode a JSON is plus.