w3c / webappsec-csp

WebAppSec Content Security Policy
https://w3c.github.io/webappsec-csp/
Other
210 stars 78 forks source link

`prerender` subresources and CSP #284

Open yoavweiss opened 6 years ago

yoavweiss commented 6 years ago

In #107 we discussed CSP in relation to prefetch. As part of the comments there, @mikewest said

"Prerender triggers the navigation algorithm, so would be governed by navigation-to"

which makes sense.

But, that doesn't cover the subresource loads that prerender then triggers. Two options I can think of: 1) They'd be governed by the prerendered HTML's CSP 2) They'd be covered by the current page's prefetch-src

I think 1) is easier from a developer's perspective, but want to see what other folks think.

annevk commented 6 years ago

FWIW, I don't agree with prerender being sufficiently captured by navigation-to. Navigation is end user visible, prerender is not. Therefore prerender should be governed by connect-src/default-src or some such.

Once prerender is allowed, it seems reasonable to use the CSP of the prerendered document, assuming it only works for same-origin resources.

mikewest commented 6 years ago

I don't agree with prerender being sufficiently captured by navigation-to. Navigation is end user visible, prerender is not. Therefore prerender should be governed by connect-src/default-src or some such.

I could live with that.

That said, I wonder if it would be better to make prefetch-src more generic, and just let it cover any pre-anythings that don't have more specific usage restrictions (e.g. prefetch, prerender, next, dns-prefetch, preconnect, etc).

Once prerender is allowed, it seems reasonable to use the CSP of the prerendered document.

This seems right to me.

assuming it only works for same-origin resources.

I'm pretty sure prerendering is meant to work cross-origin. Your favourite search engine is pretty sure you're going to visit the first link, so it ask the browser to warm things up, for example.

annevk commented 6 years ago

I guess it's fine either way, if you trust that other origin with the user's data it's already too late if they turn out to be evil.

yoavweiss commented 6 years ago

I don't agree with prerender being sufficiently captured by navigation-to. Navigation is end user visible, prerender is not. Therefore prerender should be governed by connect-src/default-src or some such.

I see the difference between prerender and a regular navigation, but don't think connect-src is a right fit. I think we can prefetch-src (falling back to default-src, just like <link rel=prefetch>) would be better.

I'm pretty sure prerendering is meant to work cross-origin. Your favourite search engine is pretty sure you're going to visit the first link, so it ask the browser to warm things up, for example.

Yup, third party prerendering is a major use-case.

mikewest commented 6 years ago

@yoavweiss: Is "prefetch" a reasonable way of talking about the various generic pre-things noted above? Should we wrap all of them up into it?

yoavweiss commented 6 years ago

SGTM

mikewest commented 6 years ago

Ok. Then I'll adjust the patch to talk about more things. We'll have to add a hook to Fetch and CSP directives for preconnect, and I have no idea where dns-prefetch is defined...

yoavweiss commented 6 years ago

Oh, I wasn't talking about preconnect and dns-prefetch... I think prefetch-src can cover prerendered resources as well as prefetched ones.

For preconnect and dns-prefetch, I'm not sure. They are destined for current navigation, and can be used to fetch all kinds of request destinations. Should we have a separate opt-in for them saying "only allow preconnect and dns-prefetch from whitelisted domains"? Or otherwise only allow them for hosts that are listed in any directive?

mikewest commented 6 years ago

I think prefetch-src can cover prerendered resources as well as prefetched ones.

Ok.

Should we have a separate opt-in for them saying "only allow preconnect and dns-prefetch from whitelisted domains"

That seems like overkill. They seem to slot pretty well either into "go connect to this thing" (e.g. connect-src), or "go pre-something this thing" (e.g. prefetch-src). Why would we ask developers to add a new directive to their policy for this?

Or otherwise only allow them for hosts that are listed in any directive.

I guess this makes some kind of sense, but I am not enthusiastic about doing this as it's more work and less clear. For example, frame-ancestors allows a set of things to embed a given page: should we include anything that can embed the given page in the set of things it wants to talk to? I'm not sure that's reasonable.

yoavweiss commented 6 years ago

OK, so @mikewest and myself discussed it and reached the following conclusions:

Mike - does that properly capture your understanding of our discussion? @annevk and @dveditz - does that make sense?

annevk commented 6 years ago

Yeah, see also https://github.com/w3c/webappsec-csp/issues/282 which summarizes that discussion too. 😊

nico3333fr commented 5 years ago

Some bypasses that could be mitigated: https://blog.mazinahmed.net/2019/01/backchannel-leaks-on-strict-csp-policy.html