Opened 10 years ago

Closed 10 years ago

Last modified 9 years ago

#1816 closed task (fixed)

Create a prototype Content Script for Google Chrome

Reported by: mikeperry Owned by: mikeperry
Priority: Medium Milestone:
Component: Applications/Torbutton Version:
Severity: Keywords:
Cc: Actual Points:
Parent ID: #1770 Points:
Reviewer: Sponsor:


We should check to see if Google Chrome's content scripts are robust enough for us to hook the javascript components we need to hook to mitigate fingerprinting and other Torbutton-related issues. The Chrome people offered to fix shortcomings if we can provide them with test cases sooner rather than later.

Child Tickets

Attachments (3)

TorMode.crx (6.1 KB) - added by mikeperry 10 years ago.
Apply content scripts to iframes. Update version to 0.0.4
TorMode-0.0.5.crx (6.1 KB) - added by mikeperry 10 years ago.
Document scoping and potential issues.
TorMode-0.0.6.crx (6.8 KB) - added by mikeperry 10 years ago.
Clean up code+comments a bit more.

Download all attachments as: .zip

Change History (18)

comment:1 Changed 10 years ago by mikeperry

Damn. Just a few minutes into this and it quickly becomes apparent that we cannot use Content Scripts to do what we want. My plan was to use content scripts in Google chrome to implement Torbutton's fingerprinting protection mechanisms, and to also work on a prototype general anti-fingerprinting addon to counter many of these issues and to light a fire under Mozilla to give us the APIs we need:

The problem is that it appears pretty clear that at least currently, there is no way for content scripts to do anything other than DOM manipulation, which does *not* include objects that can be found off of window, such as window.Date, window.plugins, window.navigator, and window.screen - all of which are crucial to wrap to provide fingerprint resistance.

The core problem is that these objects are sandboxed and shadowed by the Chrome "isolated worlds" concept:

This may mean that it is not possible to use content scripts to provide either Torbutton for Chrome protections, or to provide an anti-fingerprinting addon for Chrome, at least for the short term, or until new APIs are provided.

comment:2 Changed 10 years ago by mikeperry

Perhaps all is not yet lost. My brother pointed out that I can use a content script to insert a <script> tag into the DOM with fixed script text that may do what I want, because it should execute in the actual content window's javascript vm. I will try this today.

comment:3 Changed 10 years ago by mikeperry

Alright! Thanks to some more help from my brother, I've got this working. We can't use a script.src url directly, because then Chrome delays the load until it starts loading other page elements. However, we can stuff the thing into a function closure and then use .toString() to shove that into script.innerHTML.

The prototype I have cloaks timezone, resolution, and javascript-available user agent and plugin information. It has a few issues:

  1. It's not clear if the script.innerHTML trick is just allowing us to win a race, or if we are actually assured to run before all page script because we use "run_at": "document_start" in our manifest.
  1. It's not clear if we've covered enough protocols in our permissions section of the manifest, especially if Javascript can register custom protocol handlers like it can in Firefox.
  1. We cannot actually yet actively request that the addon be run in Incognito mode. The user has to manually tick a checkbox before it does anything at all (because it only works in Incognito mode).
  1. It's not clear if we successfully defeat all the anti-js-rootkit stuff that Greg Fleischer did against Torbutton a few years back. All his tests do fail out of the box, though.
  1. There are still other issues that remain with a proper Tor mode, most notably:
    1. Incognito specific proxy settings that are DNS-leak safe.
    2. Preventing plugins from loading, or otherwise muzzling/sandboxing them
    3. Blocking versions of the WebRequest APIs.
    4. Preventing external apps from being launched without a proper warning
    5. Odd bits of SSL state and other things that may still persist in Incognito mode

comment:4 Changed 10 years ago by mikeperry

Resolution: fixed
Status: newclosed

To install this prototype in Chrome from this bugtracker, click on the attachment, go to download, and then allow Chrome to install it. Once it is installed, go to your Extensions pane in Chrome and click "Allow this extension to run in incognito".

Then, enable incognito mode and try out:

comment:5 Changed 10 years ago by mikeperry

Eek, it turns out that it is possible to fingerprint that certain addons are installed by sourcing their chrome-extensions urls from page script. If the addon is installed, the page will source. If it is not installed, the page won't source and you can detect this by either catching an exception or registering a listener for onerror.

This is bad for Torbutton's undiscoverability requirement:

However, I'm guessing a lot of addons inject tags that source things from their own addons dir into pages they have permissions over.. Bleh. Maybe this is something we can use Web Request to handle.

comment:6 Changed 10 years ago by mikeperry

The second .crx update fixes a parse error on the last line that shouldn't have affected functionality.

comment:7 Changed 10 years ago by mikeperry

Ok, I just got back from my meeting with Adam Barth and Pam Greene at Google. Adam is familiar with Firefox js rootkit/closure busting techniques, and he tried out a few common ones but couldn't directly undo our hooks.

However, he was able to bypass them by doing anything that induced chrome to load an about:blank window, because the content scripts do not get applied. This includes:

<iframe src="about:blank" id="myframe"></iframe>
var frame = document.getElementById("myframe");

But also, more subtly:
function haxor() {

var win =3D'/');

<button onclick=3D"haxor()">Try to haxor</button>

More directly, encoding anything into a data url and throwing it in the url bar or elsewhere is also not covered by their content script injection:


So we've got to convince chrome to allow us to inject content scripts into about:blank windows and data urls.

The good news is that race conditions do not seem possible with our approach. I put a pretty fat delay loop into the content script before doing the injection, and page script did not load first.

comment:8 Changed 10 years ago by mikeperry

Also, my brother pointed out that the extension gallery is exempt from content script injection, for abuse concerns. Similar exemptions apply to other about: urls.

This means that we will have to ensure that Web Request will allow us to block all requests to this page, and to special about: urls, so that we can display a confirmation dialog to the user before they are (forcibly) navigated to them to be fingerprinted.

Changed 10 years ago by mikeperry

Attachment: TorMode.crx added

Apply content scripts to iframes. Update version to 0.0.4

comment:9 Changed 10 years ago by mikeperry

Two potential filed chromium bugs that could ruin our day if they are fixed:

We *may* be able to wrap every variable we declare inside an additional anonymous lambda to protect against this use of "with", though, so long as chrome doesn't *also* add a way to walk a javascript scope chain.

comment:10 Changed 10 years ago by mikeperry

We also need to keep an eye on the behaviors of, Object.apply() and Function.bind():

So far they don't seem to cause us any trouble because of how V8 treats 'this' and var declarations.

Also, two more related bugs we need to track:

comment:11 Changed 10 years ago by mikeperry

We should also keep an eye on this query to keep us appraised of plans to add scope-walking capabilities to V8:

So far there are no tickets open for it, which is good.

comment:12 Changed 10 years ago by mikeperry

Thanks, trac. There should be two underscores after parent in that query. It should read "parent"

Changed 10 years ago by mikeperry

Attachment: TorMode-0.0.5.crx added

Document scoping and potential issues.

Changed 10 years ago by mikeperry

Attachment: TorMode-0.0.6.crx added

Clean up code+comments a bit more.

comment:13 Changed 10 years ago by mikeperry

We should also keep an eye on the registerProtocolHandler bug:

Shouldn't cause us serious problems, but useful to track.

comment:14 Changed 10 years ago by mikeperry

Robert Hogan just landed us a window.screen spoofing option in WebKit, so we may not need to wrap that in our javascript hooks:

comment:15 Changed 9 years ago by mikeperry

Note: See TracTickets for help on using tickets.