Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add Report-To Content-Security-Policy directly in web.config

I'm trying to implement report-uri and report-to in front-end app.

report-uri:

I accomplished the goal expanding current Content-Security-Policy header value with report-uri and this is working:

<add name="Content-Security-Policy" value="default-src 'self' 'unsafe-inline' data: google.com; report-uri http://localhost:51260/api/csp/report;"/>

report-to:

Following the instructions I undertstood that I need to add two things: new Report-To header and new instruction in Content-Security-Policy so I've escaped the stringified json for report-to and added them web.config:

<add name="Report-to" value="{&quot;endpoints&quot;:[{&quot;url&quot;:&quot;https://localhost:51260/api/csp/report-to&quot;}],&quot;include_subdomains&quot;:true,&quot;group&quot;:&quot;csp-endpoint&quot;,&quot;max_age&quot;:31536000}" />          
<add name="Content-Security-Policy" value="default-src 'self' 'unsafe-inline' data: google.com; report-uri http://localhost:51260/api/csp/report; report-to csp-endpoint;"/>

but it does not work.

Unescaped value:

{"endpoints":[{"url":"https://localhost:51260/api/csp/report-to"}],"include_subdomains":true,"group":"csp-endpoint","max_age":31536000}

For reference:

  1. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri
  2. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-to
like image 604
bombek Avatar asked Mar 11 '20 09:03

bombek


People also ask

What is content security policy report only HTTP?

Content-Security-Policy-Report-Only The HTTP Content-Security-Policy-Report-Onlyresponse header allows web developers to experiment with policies by monitoring (but not enforcing) their effects. These violation reports consist of JSONdocuments sent via an HTTP POSTrequest to the specified URI.

How do I set up content security policy for my site?

Sites may also use the Strict-Transport-Security HTTP header to ensure that browsers connect to them only over an encrypted channel. Configuring Content Security Policy involves adding the Content-Security-Policy HTTP header to a web page and giving it values to control what resources the user agent is allowed to load for that page.

How do I implement a Content Security Policy (CSP) using HTTP?

If you're thinking of implementing CSP, you can take your CSP for a dry run by using the Content-Security-Policy-Report-Only HTTP header instead of Content-Security-Policy. This works just the same way as the CSP header, but it only reports on violations without actually enforcing the policy by blocking restricted resources.

What is an example of Content Security Policy?

For example, a page that uploads and displays images could allow images from anywhere, but restrict a form action to a specific endpoint. A properly designed Content Security Policy helps protect a page against a cross site scripting attack.


2 Answers

There are three versions of CSP (https://content-security-policy.com). Other than Internet Explorer, all modern browsers implement at least version 2. Browsers that only implement up to version 2 (Firefox and Safari are examples) use report-uri. Browsers that support level 3 (such as Chrome) use report-to. If a browser supports level 3, it will use report-to and ignore report-uri. If the browser only supports level 2, report-to will probably cause a warning in the console (Firefox displays the warning "Content Security Policy: Couldn’t process unknown directive ‘report-to’"), but won't cause an error.

With this in mind, you should currently include both report-uri and report-to and let the browser sort it out.

Starting with level 3, reporting is implemented with the Reporting API (https://w3c.github.io/reporting). This is currently a draft, so browsers may implement it differently. You can find an old explanation of how Chrome implements this API here: https://developers.google.com/web/updates/2018/09/reportingapi (I couldn't find a more recent version and some of the examples don't work anymore, because Chrome has been changed since this document was written). One particular piece of information from this document was very helpful: "Reports are delivered out-of-band from your app, meaning the browser controls when reports are sent to your server(s)." With CSP level 2, reports are sent immediately, while with CSP level 3, reports are sent at the discretion of the browser. This means that you may not immediately see the report. When I first implemented a CSP, I tried to test and assumed the report would be sent immediately. So when I used Firefox, I would see the report, when I used Chrome I didn't (I had to wait on an average of 30 - 60 seconds).

As a testing tool, in chrome you can go to chrome://net-export and https://netlog-viewer.appspot.com to track the reports. Go to net-export and select "Start Logging to Disk" (I just leave the default options). Select the location to save the log file. Then go to your website that is supposed to send a report when the CSP is violated. After you have done that (and checked the console to ensure a violation occurred), go back and to net-export and select "Stop Logging". At this point, you can view the contents of the log file, by going to the second link I provided (netlog-viewer). Open the file and then you will have many options in a menu on the left. The one that interests you is "Reporting". On the right of the screen you will see "Queued Reports". Assuming the report wasn't sent yet, you will see the csp-violation here (if the report has already been sent, you won't).

I said all of that to say this, I believe your code is fine. I used it in one of my websites and it worked (I changed the endpoint url, but everything else was the same). I believe your issue is trying to get a report sent when using localhost. I couldn't find any documentation to verify this claim (if someone else does, please add a comment), but I couldn't get a report sent when using localhost either. I thought it might be a security certificate issue (based on this article the Reporting API is only available in secure contexts: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts/features_restricted_to_secure_contexts), but I setup local host to use https and the report still wasn't sent. I can see the report in the Chrome reporting tool, but it never gets sent.

I hope this helps and that someone else can add to this answer.

Update: 8/29/2022

The link to https://developers.google.com/web/updates/2018/09/reportingapi is now being redirected to https://web.dev/reporting-api/. While the Content Security Policy has not changed, the Reporting API has been updated. Keep in mind that the Reporting API has not been finalized and is still "experimental" according to MDN (https://developer.mozilla.org/en-US/docs/Web/API/Reporting_API).

With this in mind the recommendation is to keep report-uri in the content security policy, but now use reporting-endpoints as a header to replace the report-to header (even though keeping both is probably best for now).

Something that can be confusing is there is a "report-to" directive in the CSP, which is used to specify the group name and a "Report-To" header. The "Report-To" header is what is being replaced by the "Reporting-Endpoints".

like image 192
joeshmoe301 Avatar answered Nov 06 '22 17:11

joeshmoe301


Coped with the same problem on local.

Firstly, your "Report-To" header is ok - i had the similar for local and it works. I even used relative url for endpoint instead of absolute one.

As @joeshmoe301 mentioned the problem was in untrusted sertificate so as soon as i made it trusted i started getting reports.

The way to get self-signed SSL certificate for windows 10 - worked for me

Secondly, there is new reporting api: Reports sent via the report-to directive have a universal format, since not only a report on CSP violation can be sent via it, but also any reports about problems that occurred in browser. The Content Security Policy violation report will have of type "csp-violation", while content of the violation report itself will be sent in the "body" field:

[{
  "age":0,
  "body":{
    "blockedURL":"https://csplite.com/tst/media/7_del.png",
    "disposition":"enforce",
    "documentURL":"https://csplite.com/tst/test_frame.php?ID=229&hash=da964209653e467d337313e51876e27d",
    "effectiveDirective":"img-src",
    "lineNumber":9,
    "originalPolicy":"default-src 'none'; report-to endpoint-csp;",
    "referrer":"https://csplite.com/test229/",
    "sourceFile":"https://csplite.com/tst/test_frame.php?ID=229&hash=da964209653e467d337313e51876e27d",
    "statusCode":0
    },
  "type":"csp-violation",
  "url":"https://csplite.com/tst/test_frame.php?ID=229&hash=da964209653e467d337313e51876e27d",
  "user_agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
}]

Note that the field names differ from their standard names of violation report, sent via report-uri:

document-uri      ->    documentURL
blocked-uri       ->    blockedURL
effective-directive ->  effectiveDirective
violated-directive  ->  violatedDirective
source-file       ->    sourceFile
original-policy   ->    originalPolicy
line-number       ->    lineNumber
status-code       ->    statusCode

And Content-Type for this api is: Content-Type: application/reports+json

Also keep in mind that reports sending by report-to are sent with delay differ to report-uri. (also mentioned by @joeshmoe301)

like image 39
kVarlamov Avatar answered Nov 06 '22 16:11

kVarlamov