Skip to content

Early Hints's relationship to CSP #687

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

Closed
annevk opened this issue Aug 20, 2018 · 24 comments
Closed

Early Hints's relationship to CSP #687

annevk opened this issue Aug 20, 2018 · 24 comments

Comments

@annevk
Copy link

annevk commented Aug 20, 2018

See w3c/preload#114.

It seems like Early Hints could potentially violate policies. Or perhaps 1xx responses need to be recommended to also include CSP policies?

@kazuho
Copy link
Contributor

kazuho commented Aug 20, 2018

Would you mind elaborating on how it could violate a policy?

103 only allows speculative evaluation of the header fields, meaning that a client must not apply the header field found in the 103 response in a way that it affects how the final response is processed.

Considering that, I would argue that it would be a bug of a client if a header field of a 103 response causes a policy violation.

Or are you arguing about a case where that approach makes the header fields of 103 response unapplicable in practice?

@annevk
Copy link
Author

annevk commented Aug 20, 2018

Early Hints allows bypassing the policy stated in the final response. I think that's a problem of sorts.

@tunetheweb
Copy link

Is the concern than the early hint includes a different policy (or no policy at all)?

Or is the concern that a hint could include a resource that would be blocked by the final policy?

For the latter the resource could potentially be downloaded but then not be used if the ultimate policy blocks it. So this shouldn’t cause an XSS is ur but may cause a privacy issue and/or information leakage (e.g. a blocked image is downloaded when it shouldn’t be, or a resource is downloaded over insecure http despite the ultimate presence of upgrade-insecure-requests).

However since both the Early Hint and the CSP are served by the same server, and any attacker with access to change either has complete control, I’m not sure how much of a problem this really is?

@annevk
Copy link
Author

annevk commented Aug 20, 2018

Both are a concern. And in complex setups not all aspects of the server are administered by the same person, so this kind of mismatch can result in issues.

@annevk
Copy link
Author

annevk commented Aug 20, 2018

(It's not clear if an Early Hint can include a policy btw, that's not defined. Perhaps I should raise a new issue for that?)

@kazuho
Copy link
Contributor

kazuho commented Aug 20, 2018

@annevk Thank you for your comments. Could you please check if my understanding (stated below) is correct?

When evaluating a link rel=preload header, the browser blocks the preload depending on the value of the "as" attribute. For example, loading of a image specified by the link header field is blocked, if the URL being contained is not allowed by the img-src property of the CSP header field.

By reading w3c/preload#37, I think that that is the expected behavior of preload.

Assuming that the above is correct, I agree with you that the specs should be interpreted that they ban fetching certain types of resources until the CSP value gets fixed in the final response. Such types includes images and fonts (the spec talks about blocking "loads"). OTOH, the rule does not apply to scripts or stylesheets, because CSP deals about "executing" or "applying" them.

Having said that, based on my understanding about CSP (stated above), I wonder preload referring to CSP has any value in terms of security (even though I think that it is a good optimization), because a server can always lie the value of the "as" attribute. For example, a server could send a link rel=preload header with as=style to initiate a load of a ".jpg" file, even in case CSP is set to "img-src=none".

To summarize, I would argue that the specs do not prevent us from fetching scripts or stylesheets designated by link rel=preload headers in a 103 response. I also argue that there is no need to block fetching other types of resources found in the 103 response.

@annevk
Copy link
Author

annevk commented Aug 21, 2018

CSP governs all fetches. So a policy that disables all cross-origin fetches could be circumvented if CSP is not applied.

@kazuho
Copy link
Contributor

kazuho commented Aug 21, 2018

@annevk My read of https://www.w3.org/TR/CSP3/ is that CSP "controls the resources which a particular page can fetch or execute" (emphasis mine), and that scripts and stylesheets are allowed to be fetched, regardless of the value of the CSP header field.

Are you suggesting that I am interpreting the text incorrectly (it could be), or that browsers do not implement that way?

Or do you agree with the interpretation that scripts and stylesheets can be speculatively fetched regardless of the value of the CSP, but consider fetching other resources by observing the value of the link rel=preload headers without consulting CSP a security concern?

@annevk
Copy link
Author

annevk commented Aug 21, 2018

It controls both fetching and execution, but that doesn't mean it doesn't control the fetching of scripts (it does).

@kazuho
Copy link
Contributor

kazuho commented Aug 21, 2018

@annevk Thank you for the answer. So CSP as a spec disallows fetching scripts or stylesheets.

Then, the issue seems to be in the hands of preload spec; I might suggest bypassing CSP rules when processing link rel=preload headers when processing a 103 response for the following reasons:

  • CSP rules are applied when the browser sees a tag that loads the resources; link preloads can be considered a way to speculatively start fetching them
  • considering the fact that the CSP header field and the link rel=preload header field are sent by the same entity, I do not think that there would be a security concern if the client starts fetching the resources designated by the link header prior tor receiving the CSP settings.

@annevk
Copy link
Author

annevk commented Aug 22, 2018

To quibble, CSP rules are applied whenever the browser fetches something in the context of a web page. I'd argue that includes 103, especially when we get origin-wide CSP policies.

It's a security concern in that a server operator now needs to be aware that CSP can be circumvented. So they would need to monitor all 103 responses somehow.

@mnot
Copy link
Member

mnot commented Oct 18, 2018

Anne, if a 103 response had both a preload Link header and a Content-Security-Policy header, would you think that workable?

@annevk
Copy link
Author

annevk commented Oct 18, 2018

Yeah, the problem still remains that server operators have to be aware of it. If one team deploys 103 without telling the security team, ... Anyway, that's what I suggested in OP and I still think that'd be acceptable.

Origin Manifest/Policy would make this less of a problem, but that doesn't seem to be happening anytime soon.

@noamr
Copy link

noamr commented Feb 28, 2022

I just went through https://www.w3.org/TR/CSP3/#goals

I didn't see anything about CSP being a "what to fetch" policy. It seems to be all about protection from content injection. The spirit of default-src: none seems to be a fallback to catch several types of resources rather than trying to be a complete request blocking mechanism.

I also don't see why server operators need to be aware that a 103 might override their CSP. All that would happen in the worst case is a redundant GET request to a resource that would later be blocked when consumed due to CSP, and the document would have no way to observe it. I fail to see the threat model of this.

One way to mitigate possible issues (that I consider edge cases) would be to allow sending a CSP header with a 103 response, enabling servers that really want to send the CSP header prior to any link headers to do so. But even if this didn't exist it's hard for me to understand the threat of redundant and inaccessible GET requests that were anyway initiated by whoever is serving the document.

@annevk
Copy link
Author

annevk commented Mar 1, 2022

The problem is exfiltration.

@noamr
Copy link

noamr commented Mar 1, 2022

The problem is exfiltration.

OK found the relevant issues.
Seems like a lot of exfiltration-related questions around CSP are left unanswered, even around the question of whether CSP should prevent exfiltration, so Early Hints starts from a shaky ground consensus-wise.

I can see some ways forward:

  1. Early Hint links have to include or come after an early hint CSP. If a new non-identical CSP comes afterwards the fetch will error.
  2. If a CSP header arrives after an early hint that makes that early hint retroactively forbidden, serve a network error and report the violation.
  3. If this is a same-origin navigation, perhaps we could treat this early hint as a prefetch from the previous same-origin document? not sure this helps as I believe early hints would have the most utility for first-time navigation to an origin.
  4. Allow same-origin early hints, which would be ignored if the CSP later claims none rather than self
  5. Defer this issue to the general conversation about exfiltration in CSP

I think (2) is not a bad solution - servers would have to be careful about their early hints not violating their own CSP, and if they do so by mistake they'll see the error immediately as the document will not be served.

@yoavweiss
Copy link
Contributor

The problem is exfiltration.

I'd argue that since there's no reasonable way for an attacker to inject Early Hints headers, the risk for data exfiltration using them is very slim, at worst.

I think (2) is not a bad solution - servers would have to be careful about their early hints not violating their own CSP, and if they do so by mistake they'll see the error immediately as the document will not be served.

CSP violation warnings make sense, but not committing the document seems like something that can significantly increase the adoption risk of Early Hints with CSP. I think it makes sense to weigh the actual risk vs. benefit of the measures we take here.

/cc @mikewest @arturjanc

@annevk
Copy link
Author

annevk commented Mar 1, 2022

I think the simplest solution here (as also suggested upthread by mnot) would be that we take CSP into account for each 103 response individually. So if the server sends a 103 response without CSP, it's not protected.

@noamr
Copy link

noamr commented Mar 1, 2022

I think the simplest solution here (as also suggested upthread by mnot) would be that we take CSP into account for each 103 response individually. So if the server sends a 103 response without CSP, it's not protected.

I'm fine with this also

@yoavweiss
Copy link
Contributor

I think the simplest solution here (as also suggested upthread by mnot) would be that we take CSP into account for each 103 response individually. So if the server sends a 103 response without CSP, it's not protected.

Makes sense to me!

@mikewest
Copy link
Member

mikewest commented Mar 1, 2022

I think the simplest solution here (as also suggested upthread by mnot) would be that we take CSP into account for each 103 response individually. So if the server sends a 103 response without CSP, it's not protected.

I'm fine with this also

This has the benefit of being consistent with our handling of <meta>, which makes sense to me.

I am curious about how early hints integrate with Fetch, though, since it's not clear to me how we pick a policy container for that response (since there's no document yet), and we'd need that for things beyond CSP (referrer policy, etc).

@yoavweiss
Copy link
Contributor

Well, that's being worked-on/discussed in whatwg/fetch#1404

@annevk
Copy link
Author

annevk commented Mar 1, 2022

Right, I think it should essentially behave as if you navigated towards a fresh document. So the policy container would be created based on the headers that are supplied with the 103 response. whatwg/html#7598 has some discussion about this. (The Fetch PR isn't particularly relevant I think as it's mainly about exposing 103 responses to the navigate algorithm.)

@noamr
Copy link

noamr commented Jan 1, 2023

I believe this can be closed.

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

No branches or pull requests

7 participants