Open Bug 1242902 Opened 8 years ago Updated 2 years ago

link rel=prefetch blocked by CSP

Categories

(Core :: DOM: Security, defect, P3)

defect

Tracking

()

People

(Reporter: scolville, Unassigned)

References

(Blocks 1 open bug, )

Details

(Whiteboard: [domsecurity-backlog3])

Attachments

(1 file)

During recent work setting up a Content Security Policy for https://addons.mozilla.org we noticed that: 
<link rel="prefetch" href="whatever"> is triggering a CSP violation which appears to be falling back to pointing at default-src as the rule violated. 

Here's a simple testcase demonstrating the behaviour:

http://yakshavings.co.uk/csp/link-rel-prefetch.html

Since there's a configuration allowing mrl.staticfil.es for img-src and script-src I wouldn't expect this violation.

Bug seen in Firefox 44.3.04 on mac and windows.

Also seen in FF Nightly 47.0a1 (2016-01-25) mac.
Adding ni? to myself so I am going to have a look at that problem.
Flags: needinfo?(mozilla)
So, I figured what's going on. Apparently we use TYPE_OTHER instead of the actual type when loading here [1] which then causes the misclassification within CSP.

I think what we need to do is, we should pass the contentPolicyType to the constr of ::nsPrefetchNode(). But that also means we have to change that *.idl to include a contentpolicytype within prefetchURI().

Nick, it seems you wrote a bunch of code for the prefetchService. Does that sound like a plan?

Since prefetchURI is scriptable, do you think there might be any issues with addons, or can we simply update the signature of prefetchURI to include a contentPolicyType after the aURI?

[1] http://mxr.mozilla.org/mozilla-central/source/uriloader/prefetch/nsPrefetchService.cpp#112
[2] http://mxr.mozilla.org/mozilla-central/source/uriloader/prefetch/nsIPrefetchService.idl#23
Flags: needinfo?(mozilla) → needinfo?(hurley)
Here is a WIP patch, but I don't think we can actually query the contentPolicy type from:

<link rel="prefetch" href="http://mrl.staticfil.es/img/beebem.png">

Not really sure how to move forward. CSP spec doesn't match anything about 'prefetch' for links, and in fact we could be loading anything.
Flags: needinfo?(hurley)
(In reply to Christoph Kerschbaumer [:ckerschb] from comment #2)
> Nick, it seems you wrote a bunch of code for the prefetchService. Does that
> sound like a plan?

I didn't, really. I moved a bunch of code around in order to parallelize our prefetches, but that was it. It required a rudimentary understanding of the code at most, so I'm probably not the best person to ask here :) Not really sure who is, either.
link prefetches could be for anything, and don't dare try to guess from the file extension! blocking them as type_other and checking default-src is probably the best we can do. But failing the prefetch should NOT cause the resource not to load... when we get to the actual image/script/whatever we need to check against the appropriate content type. That could be harder to fix, though -- might have to just bail out of prefetches if there's a CSP defined for the document.

<link rel=prefetch> is different from speculative pre-loading done by the parser -- for that we should get a usable load. If those optimizations are being done do you still need to use prefetch on AMO? This is probably not an easy thing to resolve in CSP since the standard doesn't define what the behavior is supposed to do.
(In reply to Daniel Veditz [:dveditz] from comment #5)
> link prefetches could be for anything, and don't dare try to guess from the
> file extension! blocking them as type_other and checking default-src is
> probably the best we can do. But failing the prefetch should NOT cause the
> resource not to load... when we get to the actual image/script/whatever we
> need to check against the appropriate content type. That could be harder to
> fix, though -- might have to just bail out of prefetches if there's a CSP
> defined for the document.
> 
> <link rel=prefetch> is different from speculative pre-loading done by the
> parser -- for that we should get a usable load. If those optimizations are
> being done do you still need to use prefetch on AMO? This is probably not an
> easy thing to resolve in CSP since the standard doesn't define what the
> behavior is supposed to do.

On AMO we resorted to removing all of the <link rel="prefetch> for that particular case.

FWIW I'm seeing a similar violation for what looks like implicit prefetching in relation to replaceState changes: https://github.com/mozilla/olympia/issues/1577 (If that's worth an new bug let me know and I'll file one).

Again the violation is falling back to default-src. Changing default-src to 'self' instead of 'none' works as a workaround in this particular case. The only thing I don't like is that the fallback is happening somewhat implicitly and not because we're missing a directive. It would be nice to have this behaviour documented if nothing else.
Whiteboard: [domsecurity-backlog]
Priority: -- → P3
link rel=next causes an implicit prefetch (https://bugzilla.mozilla.org/show_bug.cgi?id=175418) and therefore triggers this bug, too.
Whiteboard: [domsecurity-backlog] → [domsecurity-backlog3]
I came across this today and reproduced.
A couple thoughts on this one:

- Should we blocking this request via CSP in the first place, especially if it's on the same origin?  Whatever is being prefetched isn't being inserted into the DOM or affecting the DOM, so is it really "content"?  If all it is doing is priming Firefox's cache, it seems that it should be exempt from CSP.

- If we do continue to leave it nonexempt from CSP, and the only workaround is a non-recommended security practice *and* it doesn't actually affect any functionality on the current page, could we perhaps consider muting this particular error? Seems like it doesn't really benefit developers much to get spammed about it if there is nothing they can do, and it clutters up the console and makes them less happy about CSP.  :)

I should note that Chromium doesn't have this particular error, either because it doesn't prefetch rel="next" or because it exempts prefetches.
If we don't block it, we allow for exfiltration. I think we should absolutely treat CSP as a way to control network traffic, regardless of origin.
That's why I think we should only allow it on the same origin, perhaps if 'self' is allowed as an origin for things that can appear in <head>, as <link> can.  If 'self' allows for exfiltration, then you can probably figure out other ways to exfiltrate by injecting arbitrary tags into <head> as it is (most likely <script> or stylesheet links).

Alternatively, we could only allow from connect-src sources.  It already covers Fetch and XMLHttpRequest, which aren't really that much different from prefetching.

Another option (that I don't super care for) is to create a Firefox-only attribute called prefetch-src.

As a final option, although one that would probably take a good while to get implemented, we could update CSP3 to create a directive for it.

Currently, it's kind of a worst-case scenario: you either rip out prefetch/link (which slows things down), add a site to default-src (not a great security practice), or deal with getting spammed in the console over and over again.
Would adding another directive in CSP 3, or updating an existing directive to explicitly cover prefetch, be such a bad thing? That way we don't have to worry about Firefox only directives and we can clarify the behaviour.
CSP can't stop blocking TYPE_OTHER so most ways forward in this bug will require us to invent TYPE_PREFETCH and tag these loads with that so we can discriminate.

After that the best short-term options are 

(1) Don't block TYPE_PREFETCH (like Chrome)
   or
(2) Continue blocking, but don't report (maybe a console warning)

Clearly (2) is a lame solution because pages will be slower in Firefox (prefetch won't work) but people may not know why. In the longer term we could argue that the standard needs to be changed 

(3a) a prefetch-src whitelist (that falls back to default-src)
(3b) a default-src 'no-prefetch' directive, but allow prefetching if that's not used

Keep in mind that the standard could also be changed to (1). Less work, maybe we should just do that.
I no longer hit this with FF 53 beta. Was this fixed somewhere along the way?
I can still reproduce the issue in Firefox 53.0b5 using the testcase provided by the reporter (http://yakshavings.co.uk/csp/link-rel-prefetch.html).
I see, it's because `network.prefetch-next` was set to `false` for me.
(In reply to Anne (:annevk) from comment #10)
> If we don't block it, we allow for exfiltration. I think we should
> absolutely treat CSP as a way to control network traffic, regardless of
> origin.

Seconding this. The current behavior is secure and shouldn't be changed. I'm okay with adding a prefetch-src whitelist though.
(In reply to April King [:April] from comment #9)
> - Should we blocking this request via CSP in the first place, especially if
> it's on the same origin?  Whatever is being prefetched isn't being inserted
> into the DOM or affecting the DOM, so is it really "content"?

It's still an exfiltration vector, as seen recently in #efail
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: