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

A script tag injected into a page with a Content Security Policy that rejects inline scripts will not run [WORKING AS INTENDED] #2046

Closed
ugawk opened this issue Oct 30, 2014 · 59 comments
Milestone

Comments

@ugawk
Copy link

ugawk commented Oct 30, 2014

Reduced test script:

// ==UserScript==
// @name Hello World
// @description Hello World
// @include *
// @Version 1.0
// @grant none
// ==/UserScript==
var script = document.createElement('script');
script.textContent = "(alert('hello'))()";
document.body.appendChild(script);

This script doesn't work on
https://github.com/greasemonkey/greasemonkey/issues

On every other page it works and alert box pops up. Is this a bug with greasemonkey?

@ghost
Copy link

ghost commented Oct 30, 2014

http://en.wikipedia.org/wiki/Content_Security_Policy

GitHub forbids scripts that don't originate from their CDN (assets-cdn.github.com, collector-cdn.github.com). Consequently, Firefox will refuse to execute inline scripts.

It certainly would be nice if Greasemonkey scripts weren't affected by CSP restrictions.

@jerone
Copy link
Contributor

jerone commented Oct 30, 2014

What's the issue with just executing the code or using @require for external scripts?

@janekptacijarabaci
Copy link
Contributor

@arantius
Copy link
Collaborator

AFAIK there's no way to bypass CSP for <script> tags that happened to come from a user script, without allowing them from anywhere (which is bad). So this is probably just WAI.

@arantius arantius added this to the Pony milestone Oct 30, 2014
@ugawk
Copy link
Author

ugawk commented Oct 30, 2014

"AFAIK there's no way to bypass CSP for"

Your comment was cut off. Is it not possible to allow greasemonkey scripts to bypass CSP ?
@grant CSP

@hectorr93
Copy link

I hope GreaseMonkey can do something about this. Bookmarklets and addon's shouldn't be affected by CSP

Firefox does have about:config setting to turn off CSP completely but that is a security risk and userscript author's shouldn't be asking users to change browser settings for script to run correctly.

Can't GreaseMonkey addon edit response header to include GreaseMonkey scripts?

@arantius
Copy link
Collaborator

A <script> tag is a <script> tag. Can't enable one without enabling them all. I don't think I'm interested in building features with the sole purpose of defeating intentional security measures.

@arantius
Copy link
Collaborator

Aha .. don't try to type the word "script" surrounded by angle brackets when trying to refer to that kind of HTML tag. Anyway:

A script tag in the page is a script tag in the page. I'd be surprised if there was a way to force one of them to run, in violation of the CSP rules set, without forcing all of them to run. I'm also generally not interested in building features whose sole purpose is to defeat intentional/useful security mechanisms.

@sizzlemctwizzle
Copy link
Contributor

pdf.js apparently just turns off CSP. Unfortunately, I'm not sure how we'd do this for a script since we don't have access to the request object during injection as far as I can tell. Maybe this could be done extension-wide? If we did, would that kill CSP everywhere (or at least on any page with a script injected into it)?

@ugawk
Copy link
Author

ugawk commented Oct 31, 2014

This issue was added to "pony". What does that mean?

Getting to topic at hand, yes this requires changes made by extension not script. If CSP is turned off completely, then it would be defeating intentional security mechanisms against things like XSS. But greasemonkey scripts, like bookmarklets, are mostly used to make intentional changes. The security risk comes from installing the greasemonkey script, CSP doesn't help in that regard for greasemonkey.

Can't api be added "@grant CSP-inline" which would alter response header add "inline" to CSP?

The biggest issue is that greasemonkey disabled unsafeWindow and so injecting scripts into site was easiest alternative but now that's becoming a problem as sites use CSP.

@arantius
Copy link
Collaborator

I do not believe there is a way to securely disable CSP only for certain scripts. Look at the example in the original report. There is no request nor response to set a header on.

And to repeat: I do not intend to create new features whose sole purpose is to defeat intentional security measures.

@arantius arantius changed the title Sandbox bug? A script tag injected into a page with a Content Security Policy that rejects inline scripts will not run [WORKING AS INTENDED] Oct 31, 2014
@janekptacijarabaci
Copy link
Contributor

@mikhoul
Copy link

mikhoul commented Jul 5, 2016

@arantius It should work look here: http://i.imgur.com/Kmx7yX9.png

Implementation Considerations
9.1. Vendor-specific Extensions and Addons

Policy enforced on a resource SHOULD NOT interfere with the operation of user-agent features like addons, extensions, or bookmarklets. These kinds of features generally advance the user’s priority over page authors, as espoused in [HTML-DESIGN].

Moreover, applying CSP to these kinds of features produces a substantial amount of noise in violation reports, significantly reducing their value to developers.

Chrome, for example, excludes the chrome-extension: scheme from CSP checks, and does some work to ensure that extension-driven injections are allowed, regardless of a page’s policy.

Direct link: https://www.w3.org/TR/CSP3/#extensions

Do you think you can do do something about it @arantius ?

@pyhedgehog
Copy link

@arantius, code parts can be surrounded by backticks.
@ugawk, can't userCSP helps?

@mikhoul
Copy link

mikhoul commented Jul 8, 2016

@pyhedgehog Does userCSP permit to change relax CSP rules on site like Tweeter or Github ?

@pyhedgehog
Copy link

Seems it's not updated for newer Fx.

@mikhoul
Copy link

mikhoul commented Jul 9, 2016

I will try it next week when I will be a little bit less busy to see how it work.

It would really be useful if we can't bypass CSP based on website for power users.

Disabling it for all site is to dangerous IMO, I know that on Chrome there is at least 2 addons to disable CSP based on domain name: https://chrome.google.com/webstore/detail/disable-content-security/ieelmcmcagommplceebfedjlakkhpden AND https://chrome.google.com/webstore/detail/content-security-policy-o/lhieoncdgamiiogcllfmboilhgoknmpi

It would be really useful if @arantius integrate it in GM for power users since being able to control Userscript and addons fully is part of the W3C Working Draft, 21 June 2016.

Regards 😄

@janekptacijarabaci
Copy link
Contributor

janekptacijarabaci commented Aug 10, 2016

@mikhoul
Copy link

mikhoul commented Aug 10, 2016

@janekptacijarabaci How I can test your fork ? I don't see any new release. ❓

BTW: Big Thanks for "fixing" the CSP to be able to put inline script in all website. I will be able to use back the web as I like it 😄

Regards !

@janekptacijarabaci
Copy link
Contributor

janekptacijarabaci commented Aug 10, 2016

@mikhoul
See (e.g.)
http://www.linuxquestions.org/questions/linux-software-2/how-to-edit-files-inside-of-xpi-or-unpack-change-and-pack-again-911534/

All (i.e. changed) files are in the separate pack (see above the test branch)

  • "Clone and download" => "Download ZIP"

@mikhoul
Copy link

mikhoul commented Aug 10, 2016

@janekptacijarabaci

Thanks a lot for the help ! 😄

I'm not familiar with Github except to leave comment and other basic things.

I can do many things in JS but I never took a basic course to know the fundamentals... so sometime I lost lot of time to understand basic things. My next goal is to stop and follow a basic JS course online to stop to be stuck with basic issues ;-)

How I can know if your fork will be integrated in the main branch ? Like I told you I'm not familiar with Github over "basic" use. I'd like to be able to follow to know when you will make an update to apply it on my side.

Right now I applied it on the top of the latest beta, if I see something "wrong" I will let you know, later this week after I will finish a project I will have more time to test the CSP on site that restrict "inline JS".

Thanks again for your time, it's really appreciated. 😋

@janekptacijarabaci
Copy link
Contributor

janekptacijarabaci commented Aug 10, 2016

How I can know if your fork will be integrated in the main branch ?

Maybe never will be... :-)
It's not my decision...

@mikhoul
Copy link

mikhoul commented Aug 10, 2016

@janekptacijarabaci Will you update your fork ? I'd don't mind to update manually the XPI but I 'd like to know when you update your version 😆

Regards ! 🐸

@janekptacijarabaci
Copy link
Contributor

janekptacijarabaci commented Aug 11, 2016

This will not be added to my fork (certainly not in the near future). This is just a thing for testing.

@mikhoul
Copy link

mikhoul commented Aug 11, 2016

@janekptacijarabaci Is there a way I can add it "safely" manually at each future release ?

If you can provide me the steps to "inject" the change that allow CSP to be allowed I would be grateful.
This way I could add/inject it at each release myself 😇

Regards !

@janekptacijarabaci
Copy link
Contributor

I don't know how to describe the steps (which are both simple and safe) to do it (for all future versions).

But... (this is true only for this moment!):
You can replace this file (modules/requestObserver.js) with the new file from the test branch.

Hovewer, if you use it, you do it at your own risk!

Through we are very off-topic...

@idiotWu
Copy link

idiotWu commented Jun 23, 2017

Ran into same issue when I was trying creating a web worker from blob url (blob://) on Twitter. I'm afraid @lainverse's suggestion might not work for me because we can't add nonce attribute to worker scripts :(

@lainverse
Copy link

Shouldn't hash help? Looks like both injection methods are needed.

@idiotWu
Copy link

idiotWu commented Jun 23, 2017

Possibly not. The request to fetch worker script is sent from browser, so we have nothing to do with it.

Currently I am using another extension to modify CSP headers, but I don't think it's a good idea to bypass sites' security restrictions like this.

@allo-
Copy link

allo- commented Jun 23, 2017

What is the problem with nonce (not a sri hash)? You inject a nonce for each script/style into the CSP-Header and use the nonce with the injected script/style tags.

@idiotWu
Copy link

idiotWu commented Jun 23, 2017

@allo- yep, but worker scripts are loaded via new Worker(url), not script tags. Since it's a native DOM API, I am not able to add a nonce to it.

P.S. My current workaround is to add worker-src blob: to CSP headers. You can try out this repo if you want to test/repro it.

@lainverse
Copy link

Wouldn't worker-src sha256-... work? You won't be able to put generated code like this, but if script for worker is static this should work.

@idiotWu
Copy link

idiotWu commented Jun 23, 2017

Just tried but still failed, I think hashes only work for inline scripts. In my tests, inline script with the same contents passed, but external scripts failed.

@allo-
Copy link

allo- commented Jun 23, 2017

You do not use hashes for inline scripts, as somebody who can inject a script, can inject the matching hash. So it needs a nonce. On the other hand, there is SRI for external scripts and url-based rules.

Wouldn't worker-src sha256-... work? You won't be able to put generated code like this, but if script for worker is static this should work.

I think the security considerations are the same as for the website owner himself: If you want to use a static worker, a hash or nonce work, if you need dynamic ones, you need to be more liberal with the CSP rules. Somebody who writes a script needs to consider the same things as the website owner.

Respecting the owners CSP to a level, which makes it impossible to script the site is against the idea of greasemonkey, which should implement features, which aren't supported by the owner. So I think some CSP rules should be disabled, if it won't work otherwise.

@mikhoul
Copy link

mikhoul commented Jun 24, 2017

Currently I am using another extension to modify CSP headers,

@idiotWu Which extension do you use ?

Regards :octocat:

@idiotWu
Copy link

idiotWu commented Jun 24, 2017

@mikhoul Content Security Policy Override, an extension for Chrome browser. The following is my configs:

[
  ["https://twitter\\.com/*", [
    ["worker-src|$", "worker-src 'self' blob:"]
  ]]
]

@arantius arantius modified the milestones: Pony, Bankruptcy Jul 25, 2017
@lainverse
Copy link

lainverse commented Jul 25, 2017

Hm... So, no plans to implement any methods to bypass CSP for scripts injection?
And what is that "Bankruptcy" milestone is anyway?

@Swyter
Copy link

Swyter commented Jul 25, 2017

This sucks. Closing it is the easy way out instead of figuring out a problem that is only going to get worse as more sites start to use CSPs. It's pretty clear that there's a need for it, don't ignore it.

@0xallie
Copy link

0xallie commented Jul 25, 2017 via email

@Sxderp
Copy link
Contributor

Sxderp commented Oct 18, 2017

Just as an update. For anyone following. The Mozilla folks had their sights on allowing this for a couple years now. Accordingly, some new patches have been pushed, here and here, which should resolve these issues. Unfortunately they're set for merging into the Firefox 58 branch.

@rslifka
Copy link

rslifka commented Nov 23, 2017

@jerone @arantius The main reason one might want to do this is to iterate quickly on your own code included in @require directives. It's difficult to engineer a UserScript when a well-factored codebase means not placing your entire source in a single file 😄

  • Not placing your code in a single file means using a @require directive to include it...
  • Which caches it...
  • Which means you can't update it once you've shipped it.

This problem is exacerbated during development:

  1. Write your code in your fully-featured, customized editor you've worked with for years (i.e. not the native *Monkey editor)
  2. CTRL-A, CTRL-C
  3. Switch to Chrome
  4. Select GreaseMonkey tab with editor open
  5. CTRL-V
  6. Select application tab
  7. Refresh

It's a pretty painful workflow.

Dr Nic. wrote about this nearly ten years ago, before the proliferation of CSPs so his approach worked back then. I can't think of a way to do it now since there's no way to include an external resource and there's no way to invalidate the GM cache that I've been able to find.

Any advice here?

Thanks!

@rslifka
Copy link

rslifka commented Nov 23, 2017

@nyuszika7h I'm using TamperMonkey and getting this error. Is there a workaround?

VM2847:22 Refused to load the script 'https://openuserjs.org/src/libs/sizzle/GM_config.js' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval' https://apis.google.com https://www.google-analytics.com ...

According to the TM folks, not much they can do.

Tampermonkey/tampermonkey#296

@jsamr
Copy link

jsamr commented Aug 26, 2018

@arantius
A folk on this bugzilla ticket suggested to use contentScripts API to bypass CSP restrictions.

Can’t you use the the contentScripts API¹?
¹ https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/contentScripts

@Cerberus-tm
Copy link

@rslifka A bit belatedly: isn't the conventional solution to include the version number in the name of the @require file, like the way Jquery and simiar .js files are dealt with by Google and others? So, when you change the @require file, you change the version number in the name of the file and upload it; and you change the file name in the @require line in the main script accordingly. So the updated main script will automatically download the new version of the library file.

@rslifka
Copy link

rslifka commented Aug 27, 2018

@Cerberus-tm yep, still a pretty onerous workflow to go through all those steps when developing locally :)

I've solved this by having a development-mode UserScript that references file:// URLs, and enabled local file access in TamperMonkey in the Chrome extension settings. Works great!

@Cerberus-tm
Copy link

@rslifka Ah, that sounds smart. I wonder whether this would also work with Greasemonkey in Firefox.

@ajloveslily14
Copy link

Apologies if this has been mentioned in this thread already, but FYI, anyone who needs CSP support can use Tampermonkey, which already handles this.

How does it handle it? I can't seem to find any documentation for it and it is causing me issues...

@piratesephiroth
Copy link

Apologies if this has been mentioned in this thread already, but FYI, anyone who needs CSP support can use Tampermonkey, which already handles this.

How does it handle it? I can't seem to find any documentation for it and it is causing me issues...

I believe they're talking about the option at the bottom of the advanced settings.

@ajloveslily14
Copy link

Apologies if this has been mentioned in this thread already, but FYI, anyone who needs CSP support can use Tampermonkey, which already handles this.

How does it handle it? I can't seem to find any documentation for it and it is causing me issues...

I believe they're talking about the option at the bottom of the advanced settings.

Ah, I found the setting and it's enabled. Still having issues though...

Repository owner locked as off-topic and limited conversation to collaborators Feb 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests