[tbb-dev] Is JS monkey patching viable as a fingerprinting countermeasure?

Mike Perry mikeperry at torproject.org
Mon Sep 1 20:15:40 UTC 2014

Arthur D. Edelstein:
> Hi All,
> I'm wondering about the history of JS fingerprinting mitigation in Tor
> Browser. What prompted the change of approach from JavaScript hooks to
> C++ patches? I had read something about a race condition discovered,
> but I haven't found more details.
> I've been thinking about the idea of developing a C++ patch for Tor
> Browser (and Firefox) that allows extensions to securely replace
> arbitrary members (functions and properties) of the global window
> object at runtime, before content is loaded. By "secure" I mean that,
> by design, there would be no workaround for content scripts to access
> the original window object members. (Maybe this capability already
> exists -- I don't know.)
> The advantages of this monkey patching approach over addressing
> fingerprinting vulnerabilities with C++ patches is
> (1) it would (I think) simplify fingerprinting countermeasures, and
> (2) it would reduce the number of Firefox C++ patches that Mozilla
> needs to accept.
> Is this idea worth pursuing further?

Possibly, but even if we address all the race conditions and edge cases
(like javascript: urls and data: urls that contain script), historically
JS hooking is very fragile, with lots of ways to undo/break it cropping
up regularly in new releases.

IIRC, such "secure"/"sealed"/"non-configurable"/non-revocable hooking
recently became standardized as part of Object.defineProperty,
Object.seal, and friends, but this may still have issues. Some things
might still be forbidden from being overridden for various reasons. The
last time I went down this road, it was an endless sinkhole of issues,
and I only did it because patching the browser was not an option at that

On top of this, it doesn't allow us to cleanly hook events, callback
parameters, and other async things. In some cases, we can probably work
around this by hooking the callback registration to install our own
wrapper callbacks that alter their args before passing them in to the
registered callback, but that too takes care to ensure that the true
arguments cannot be discovered by inspecting the callchain and
associated parent scopes from inside the final content's callback.

It also won't help with CSS-based vectors for fingerprinting, or
complicated interactions between styling and JS.

It's something to consider if it really looks like Mozilla won't take
any of our fingerprinting defenses, but I think we should continue to
prioritize direct patches for now.

That said, if you see a clean way to create an API to do secure script
injection and feel like hacking it up real quick, feel free. It may
prove useful eventually, but I suspect we'll uncover a whole slough of
surprises once we actually try to use it. We'll probably also need
regression tests in-tree for every single function/callback/property we
hook, to make sure that an implementation change doesn't suddenly break
our ability to hook something in the way we want.

Mike Perry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Digital signature
URL: <http://lists.torproject.org/pipermail/tbb-dev/attachments/20140901/eaed8a8c/attachment.sig>

More information about the tbb-dev mailing list