andersju / webbkoll

An online tool that checks how a website is doing with regards to privacy
MIT License
266 stars 28 forks source link

[Feature Request] Detect use of report-uri and report-to directives #19

Closed ghost closed 4 years ago

ghost commented 4 years ago

Several HTTP response headers allow server admins to set the report-uri or the (upcoming) report-to (https://w3c.github.io/reporting/) headers, e.g., Content-Security-Policy, Expect-CT, and NEL (https://w3c.github.io/network-error-logging/).

What happens if headers are present?

As soon as a web client with support for these directives comes across such headers and produces an event (e.g., violation of the CSP, network-level error), the web client transparently sends data to a (third-party) reporting server (e.g., report-uri.com or uriports.com). This data includes the client's IP address, User-Agent, and other protocol-/error-specific information.

What is the issue for privacy?

"Transparency" means that network traffic to the reporting server is invisible for most users. They must actively enable developer options of their web browser or monitor their network traffic with other tools to detect this traffic.

Users must also actively prevent network traffic to reporting servers by disabling client-side support for the reporting directives or blocking network traffic to specific domain names.

What should be detected by Webbkoll?

Webbkoll should detect and show the presence of report-uri/report-to directives since they can be awful for privacy.

We have observed that many websites use report-uri.com or uriports.com for error reporting, so these are third-party connections to centralized providers.

Further information

See also the privacy considerations mentioned in the linked specs of Report-To/NEL (Network Leakage, Cross-origin correlation, "the stored NEL policy could be used as a 'supercookie'", "an attacker could abuse NEL reporting to probe the user's network configuration, or to scan for servers on the user's internal network").

andersju commented 4 years ago

Great idea! Thanks for the detailed suggestion. I'll implement this as soon as I find some time.

ghost commented 4 years ago

A quick and dirty CLI solution could be:

curl -I -Ss [url] | grep report

No output means that there is no report, report-uri, or report-to directive = good for privacy. Any output (except errors) likely means that there is at least one report, report-uri, or report-to directive = can be bad for privacy since there could be traffic to third parties.

andersju commented 4 years ago

Thanks. I've done some initial work on this now (783e78d). You can try it out on https://webbkoll-dev.dataskydd.net/. New section under CSP.

Checking for mere presence of report-uri / report-to isn't enough; we also need to check whether the specified URI(s) are third-parties or not, which means parsing. I added support for CSP's report-uri (deprecated, but the most compatible option, so most common) and report-to directives (supported by Chrome but not Firefox, and apparently now also deprecated, see below).

The Reporting API seems to be very much in flux; just this month the Report-To header was renamed Reporting-Endpoints, and the format changed from JSON to Dictionary Structured Header. I'll add support for that when things settle down and browsers start supporting it.

Will have a look at Expect-CT and NEL as soon as I can.

ghost commented 4 years ago

Checking for mere presence of report-uri / report-to isn't enough; we also need to check whether the specified URI(s) are third-parties or not, which means parsing.

Indeed, thanks for pointing this out. :+1:

Thanks. I've done some initial work on this now (783e78d). You can try it out on https://webbkoll-dev.dataskydd.net/. New section under CSP.

Thanks for your great work.

report-to vs. Report-To

The Reporting API seems to be very much in flux; just this month the Report-To header was renamed Reporting-Endpoints, and the format changed from JSON to Dictionary Structured Header. I'll add support for that when things settle down and browsers start supporting it.

report-to directives (supported by Chrome but not Firefox, and apparently now also deprecated, see below

I think these are two different things:

In summary, report and report-uri are legacy parameters for existing HTTP response headers. report-to is the new parameter for existing HTTP response headers. And Reporting-Endpoints will be the new HTTP response header that defines endpoints for the report-to parameter set by other HTTP response headers. (Correct me if I'm wrong.)

So the actual URLs can be either set by report and report-uri per HTTP response header, or there are set once by the Reporting-Endpoints header and different HTTP response headers point to this.

Examples

The following Content-Security-Policy sets the legacy report-uri parameter and additionally the upcoming report-to parameter. The report-to parameter points to the "default" endpoint which is set by the Report-To header afterward.

Content-Security-Policy default-src 'none'; img-src 'self' https://…; style-src 'self' 'unsafe-inline'; font-src 'self'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'; block-all-mixed-content; report-uri https://reporting-website; report-to default

Report-To {"group":"default","max_age":10886400,"endpoints":[{"url":"https://reporting-website"}],"include_subdomains":true} (legacy version)

Reporting-Endpoints {"group":"default","max_age":10886400,"endpoints":[{"url":"https://reporting-website"}],"include_subdomains":true} (new version according to your link)

Other response headers:

X-XSS-Protection: 1; report=https://reporting-website (deprecated header using the legacy "report" parameter)

Expect-CT enforce, max-age=21600, report-uri="https://reporting-website" (uses the legacy "report-uri" parameter)

NEL {"report_to":"default","max_age":2592000,"include_subdomains":true,"failure_fraction":1.0} (uses the new "report-to" parameter that points to the "default" endpoint set by "Reporting-Endpoints")

Another HTTP response header with reporting support is Content-Security-Policy-Report-Only.


[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri

andersju commented 4 years ago

Thanks very much for your detailed comments. I haven't forgotten this, just been way too busy lately. In May I'll have a lot more time and will get back to this.

andersju commented 4 years ago

Added support for Expect-CT and NEL, in addition to Content-Security-Policy and Content-Security-Policy-Report-Only report-uri/report-to. Try it on https://webbkoll-dev.dataskydd.net/. Will add support for Reporting-Endpoints with the new format when some browser starts to use that.

(Didn't add a check for X-XSS-Protection reports, because Firefox never supported it and both Chrome and Edge have now removed support for it [1], [2])

andersju commented 4 years ago

Alright, this is now live on https.//webbkoll.dataskydd.net too!

(Still need German translations for 10 strings, if anyone reading this is up for that: https://weblate.dataskydd.net/translate/webbkoll/main/de/?q=state:%3Ctranslated -- it's possible to make translation suggestions without logging in.)