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

Site CSP's prevent surrogates from being loaded. google-analytics on Twitter for example #2823

Closed
cowlicks opened this issue Jul 26, 2017 · 8 comments

Comments

@cowlicks
Copy link

cowlicks commented Jul 26, 2017

When I go to https://twitter.com with uBlock enabled I see

Refused to load the script 'data:application/javascript;base64,KGZ1bmN0aW9uKCkgewoJLy8gaHR0cHM6Ly9kZXZl…because it violates the following Content Security Policy directive: "script-src https://connect.facebook.net ... https://www.google-analytics.com 'nonce-IXZr3HyzACNQVWtSHdlFsQ==' 'self'".

Decoding some of the stuff in the error gives:

atob('KGZ1bmN0aW9uKCkgewoJLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYW5hbHl0aWNzL2Rldmd1aWRlcy9jb2xsZWN0aW9uL2FuYWx5dGljc2pzLwoJdmFyIG5vb3BmbiA9IGZ1bmN0aW9uKCkgewoJCTsKCX07Cgl2YXIgbm9vcG51bGxmbiA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiBudWx')

(function() {
	// https://developers.google.com/analytics/devguides/collection/analyticsjs/
	var noopfn = function() {
		;
	};
	var noopnullfn = function() {
		return nul

Which shows it's from the google analytics surrogate.

One or more specific URLs where the issue occurs

https://twitter.com/

Screenshot in which the issue can be seen

ublock-twitter

Steps for anyone to reproduce the issue

go to twitter.com while logged in
look at the console

Your settings

[If you fail to provide this info, I will mark the issue as invalid. Lists all settings which differs from default settings]

  • OS/version: arch linux 4.1.9
  • Browser/version: chrome v 56
  • uBlock Origin version: 1.13.8
Your filter lists

I've never touched these, the defaults I guess



Basically the sites CSP prevents loading scripts with data URI's.

I've been looking in to how to fix this for Privacy Badger, see this issue. There is a similar unsolved problem for Decentraleyes see here (cc @Synzvato).

Here is a dump of notes on the topic, info from others is welcome:

can we modify the CSP to make it work?

We'd have to add a nonce or a hash of the redirected content. This would need to be done when we see the maine_frame of the document, which is before we know what we'd need to block. So we don't know ahead of time what tag would have to get the nonce. I also don't know what script would get surrogated, so I don't know its hash.

Is there another way?

Maybe redirect to something other than a data URI?

Would this still have CSP issues?
Maybe I could redirect to a file. But managing a bunch of surrogates in induvidual files sounds like a PITA. I'd also like to dynamically generate surrogates eventually.

Could I use a filesystem api to generate the files on the fly? Could I make a "fake" file? idk

Maybe I could redirect to a proxy file that receives messages from the extension, then dynamically defines the surrogate script? This probably cause raceconditions since the scripts' names are not immediately defined. I should try chrome.tabs.executeScript(..., 'document_start').

Chrome vs Firefox

Chrome requires that blocking webrequest listeners return a value like {foo: bar}, however Firefox allows you to return a promise.

This means that in chrome your blocking webrequest cannot depend on an async function to get its result. But in firefox you can.

So in FF but not Chrome, we could wait to inject a script, and for the script to signal back when it is ready.

https://developer.chrome.com/extensions/webRequest
https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest

Other ideas?

@gorhill
Copy link
Owner

gorhill commented Jul 26, 2017

I don't plan to have uBO lower CSP rules set by a site. In my opinion, being able to inject a surrogate is less important than not relaxing existing CSP ruleset.

@cowlicks
Copy link
Author

@gorhill To be clear, I'm not suggesting that we lower the CSP for a site. We should not have to make a compromise like that to inject surrogates.

@gorhill
Copy link
Owner

gorhill commented Jul 26, 2017

I always assumed this could be fixed by using web_accessible_resources, but this would allow a site's javascript code to precisely identify that uBO is in use, and another problem is that I would no longer be able to add/remove/modify/fix surrogate scripts without releasing a new version of the extension, the surrogates would need to be declared in the manifest.

@gorhill
Copy link
Owner

gorhill commented Jul 26, 2017

I should try chrome.tabs.executeScript(..., 'document_start')

This won't work, the script will be executed in the content script (isolated) world.

@cowlicks
Copy link
Author

I filed a chrome bug. I don't think a website's CSP should apply redirects caused by webextensions. https://bugs.chromium.org/p/chromium/issues/detail?id=749236

@gorhill re: that won't work:
I was imagining something like:

function runInWebsite(code) {
  let uri = makeDataUri(code),
    injected = 'document.write(\"<script src=' + uri + '></script>\");';
  chrome.tabs.executeScript(..., injected,  'document_start');
}

which would run code in the content script that injects the desired script.

@cowlicks
Copy link
Author

Privacy Badger and it's user's would appreciate it if you could advocate for getting this bug fixed on the chrome issue tracker. I think your voice might help prioritize it.

https://bugs.chromium.org/p/chromium/issues/detail?id=749236#c5

@gorhill
Copy link
Owner

gorhill commented Feb 15, 2018

Fixed with 17930cc.

@gorhill
Copy link
Owner

gorhill commented Feb 16, 2018

@cowlicks

I always assumed this could be fixed by using web_accessible_resources, but this would allow a site's javascript code to precisely identify that uBO is in use

I worked around this issue by requiring a fetch to any of the web accessible resources ("WAR") to be made with a valid secret token -- which secret token is initialized at extension launch time with a random value.

As long as the WAR are only used internally extension-side, and never exposed to the DOM, then I see no way for the web pages to be able to see these WAR, and thus no way to directly detect the extension through its WAR.

The access to the content of the /web_accessible_resources/ folder is controlled by a webRequest.onBeforeRequest listener. The listener will redirect to a non-web accessible resource when it fails to find the secret in the URL of the resource being fetched.

Now regarding:

another problem is that I would no longer be able to add/remove/modify/fix surrogate scripts without releasing a new version of the extension, the surrogates would need to be declared in the manifest.

I only import as "web accessible resources" those which are to be used for redirection purpose. At this point these resources used specifically for redirection purpose change very rarely[1], less frequently than the extension itself is updated, so I found acceptable to forfeit the ability to dynamically update these specific resources.


[1] Last time was more than four months ago.

gorhill added a commit that referenced this issue Apr 30, 2019
Related issue:
- uBlockOrigin/uBlock-issues#550

Related Chromium issue (I can't access it):
- https://bugs.chromium.org/p/chromium/issues/detail?id=957866

Findings so far: affects browsers based on Chromium 74.
I could not reproduce the issue with either Chromium 73 or
Google Chrome 75.

This commit is a mitigation: to prevent sites from using
uBO's internal WAR secret for tracking purpose. A secret
can be used for at most one second, after which a new secret
is generated.

The original issue related to the implementation of
secret-gated web accessible resources is:
- #2823
MasterKia referenced this issue in uBlockOrigin/uAssets Aug 13, 2023
Unfortunately, the flawed conclusions people are reaching because of
this flawed tool are all over the place, including some spamming results
from this pointless tools in uBO's own thread on Wilders Security despite
advises to refrain from using the tool to evaluate content blockers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants