Page CSP should not apply to content inserted by content scripts.

NEW
Unassigned

Status

()

Toolkit
WebExtensions: General
P3
normal
a year ago
14 hours ago

People

(Reporter: kmag, Unassigned)

Tracking

(Blocks: 1 bug)

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: triaged)

(Reporter)

Description

a year ago
+++ This bug was initially created as a clone of Bug #1207394 +++

This is a follow-up to bug 1254194 comment 29.

In Chrome, web page CSP is not supposed to apply to content inserted by a content script. So, the following should all work, in theory:

* Injecting an inline <script> node should execute the script in a page with "script-src 'none'"
* Injecting an image from "http://example.com" into a page with "default-src 'self'" should load the image.

The following do not work in Chrome, but they seem to prefer that they would:

* Injecting a node with an "onclicked" listener into a page with "script-src 'none'" does not execute the listener, because the script is not executed during the call from the content script that created it.
(Reporter)

Updated

a year ago
Duplicate of this bug: 1267291
(Reporter)

Comment 2

a year ago
Dan, do you have any thoughts on how much of this behavior we want to copy? I'm actually not inclined to implement it at all, except to the extent that add-ons should be allowed to inject resources packaged with the extension.
Flags: needinfo?(dveditz)
We favor the desires of the user above the page author. We usually assume that the add-on is acting on the user's behalf (the user chose to install it) so it'd be nice if add-ons could bypass CSP. Although sometimes they do slimy stuff for themselves so it's also nice when what they're doing is explicit so reviewers can check it out.

We also are fighting an architecture that is hard to change. If something sticks in an <img> tag, that results in an image load generated by that page. At the networking/nsIContentPolicy level where CSP is enforced we can't tell the difference between script in the page creating that <img> tag and an add-on or chrome creating it.

This is not special to web extensions, and we have essentially this feature request for regular add-ons on file somewhere; I'd call this a dupe of that one. But you're here and seem to have the energy to fight this battle so here are two possible ways to "fix" it.

a) What I've suggested before is to add a method to the internal CSP that lets us expand the policy, rather than the current mechanism that only lets additional content policies tighten the policy. So a Flickr mashup could call this API and add "img-src *.flickr.com" or maybe "all-src *.flickr.com" (I just made up all-src -- we'd need something to override all policies, not a default to be used if other policies weren't set). For WebExtension and Add-on SDK addons this override could be in the add-on metadata (e.g. manifest.json) and easy to review for sanity.

b) I don't think we know in all the places, but it's possible that for DOM-based insertion (as opposed to parser-based like setting innerHTML) we still know the script principal by time we're calling AsyncOpen2 and can use that rather than the page principal. I get 167 non-test hits for AsyncOpen2 so this would be a painful and error-prone approach.
Flags: needinfo?(dveditz)
(Reporter)

Comment 4

a year ago
OK, I'll try to figure out how doable this is, then.

I think we should still respect some restrictions, though, and at least forbid loading non-secure resources into secure pages with policies that forbid it.

Comment 5

a year ago
I'm facing the same problem right now with my extension. I would opt for bypass CSP. As Daniel Veditz mention, the user chose to install the add-on with all pros (new features...) on cons (permissions request...). So CSP is just another entry on that list, depending on your point of view part of pro or con ;)

What would be a good workaround around this to bypass the CSP? I was thinking about using a background script, but that sounds like a lot of overhead just to make my extension working in Firefox.

Comment 6

a year ago
Any word on when this might get fixed?  Several of my addon's beta testers are running into this bug, and a lot more of the regular users will probably be experiencing it next month when Firefox 48 releases.
(Reporter)

Comment 7

a year ago
This won't be fixed any time in the next few months.

Comment 8

10 months ago
A possible solution: Provide an API to convert blobs to moz-extension: URIs. AIUI those URIs bypass CSP, unlike blob: URIs. So images could be downloaded as blob via XHR, converted to an extension URI and then injected as <img src="moz-extension:...">

It requires extra work by addon authors, but that way the browser won't have to track which parts of the DOM would have to be treated as privileged somehow. The concept of DOM ownership is murky anyway. It's a shared resource between addons and the page.


An alternative would be an API that allows addons to whitelist patterns of content they intend to load into a page. The downside is that it is more coarse-grained than the blob approach and thus increases the potential exploit surface - but only by the whitelist - for malicious scripts that makes it into the site.
(Reporter)

Comment 9

10 months ago
(In reply to The 8472 from comment #8)
> A possible solution: Provide an API to convert blobs to moz-extension: URIs.
> AIUI those URIs bypass CSP, unlike blob: URIs. So images could be downloaded
> as blob via XHR, converted to an extension URI and then injected as <img
> src="moz-extension:...">

It would be much easier to just treat blobs with moz-extension: origins as CSP-exempt, like we do for moz-extension: URLs themselves. Feel free to file a separate bug for that, and I'll look into implementing it.

> It requires extra work by addon authors, but that way the browser won't have
> to track which parts of the DOM would have to be treated as privileged
> somehow. The concept of DOM ownership is murky anyway. It's a shared
> resource between addons and the page.

This is something that we're going to have to do regardless.
Blocks: 1283173

Updated

8 months ago
Component: WebExtensions: Untriaged → WebExtensions: General

Updated

5 months ago
webextensions: --- → ?

Comment 10

4 months ago
Possible dupe mentioned in comment 3 is bug 615708.

Updated

3 months ago
webextensions: ? → ---
(Reporter)

Updated

2 months ago
Blocks: 1355213

Updated

2 months ago
Duplicate of this bug: 1363139
(Reporter)

Updated

a month ago
Duplicate of this bug: 1366467

Comment 13

24 days ago
On the GM issue tracker[0] the idea was brought up to inject per-userscript nonces into each -src rule of CSPs for each page load which could then be exposed to content scripts via an API. I think this is cleaner than "DOM ownership" because ownership could easily lead to transitive privilege leaks if that also applies to <script> or <iframe> elements.


[0] https://github.com/greasemonkey/greasemonkey/issues/2046#issuecomment-304908132
It looks like the Augury team has run into this issue where they can't inject their own scripts via a content script.

https://github.com/rangle/augury/blob/dev/src/content-script.ts#L32
(Reporter)

Comment 15

19 hours ago
(In reply to Bryan Clark (DevTools PM) [:clarkbw] from comment #14)
> It looks like the Augury team has run into this issue where they can't
> inject their own scripts via a content script.
> 
> https://github.com/rangle/augury/blob/dev/src/content-script.ts#L32

Content from extensions should be immune to CSP. They just can't inject web content which would violate a page's CSP.

Updated

14 hours ago
See Also: → bug 1294996
You need to log in before you can comment on or make changes to this bug.