To help reduce information available to fingerprinting, we should randomize or truncate the values returned from Date(), event.timeStamp, and interval timers. I've never thought this was a useful thing to do before, because Tor latency is high enough and variable enough that most machines using NTP should be well concealed within the noise.
However, bug legacy/trac#1261 (closed) brings up a good point about javascript being able to measure the time intervals of various things (such as typing, but really it could be anything) to produce a fingerprint.
Unfortunately, we may need Firefox support for this, unless their javascript engine has changed to allow hooking of the Date() object again.
Designs
Child items ...
Show closed items
Linked items 0
Link issues together to show that they're related.
Learn more.
Trac: Description: To help reduce information available to fingerprinting, we should randomize the values returned from Date(). I've never thought this was a useful thing to do before, because Tor latency is high enough and variable enough that most machines using NTP should be well concealed within the noise.
However, but bug legacy/trac#1261 (closed) brings up a good point about javascript being able to measure the time intervals of various things (such as typing, but really it could be anything) to produce a fingerprint.
to
To help reduce information available to fingerprinting, we should randomize the values returned from Date(). I've never thought this was a useful thing to do before, because Tor latency is high enough and variable enough that most machines using NTP should be well concealed within the noise.
However, bug legacy/trac#1261 (closed) brings up a good point about javascript being able to measure the time intervals of various things (such as typing, but really it could be anything) to produce a fingerprint.
Unfortunately, we may need Firefox support for this, unless their javascript engine has changed to allow hooking of the Date() object again.
This seems like a research problem. Randomizing the values naïvely won't actually keep a clever program from getting a value for Date; it will just call Date 10 times and take the mean.
Instead, we could quantize Date(), and randomize the cutoffs between the quanta, so that the value of Date remains the same (say) for 3.3 seconds minus a value chosen uniformly at random from between .6 and 0. Would this break programs people need? Probably. Would this defeat cadence attacks? Who can say; that's the research problem.
Rough guess here. Depends on how centralized the JS interpreters timesource is. It may be all over the place, and far from config settings to control it. Also, some testing of youtube and various HTML5 demo sites should be performed, especially those involving rendered graphics and synchronized animations.
Trac: Points: N/Ato 16 Description: To help reduce information available to fingerprinting, we should randomize the values returned from Date(). I've never thought this was a useful thing to do before, because Tor latency is high enough and variable enough that most machines using NTP should be well concealed within the noise.
However, bug legacy/trac#1261 (closed) brings up a good point about javascript being able to measure the time intervals of various things (such as typing, but really it could be anything) to produce a fingerprint.
Unfortunately, we may need Firefox support for this, unless their javascript engine has changed to allow hooking of the Date() object again.
to
To help reduce information available to fingerprinting, we should randomize or truncate the values returned from Date(), event.timeStamp, and interval timers. I've never thought this was a useful thing to do before, because Tor latency is high enough and variable enough that most machines using NTP should be well concealed within the noise.
However, bug legacy/trac#1261 (closed) brings up a good point about javascript being able to measure the time intervals of various things (such as typing, but really it could be anything) to produce a fingerprint.
Unfortunately, we may need Firefox support for this, unless their javascript engine has changed to allow hooking of the Date() object again. Summary: Torbutton should randomize times from Date() to Tor Browser should provide JS with reduced time precision
Related to this, we will need to quantize interval timers as well. Not sure if we'll get that for free by quantizing time, or if it will be additional work. It probably will be additional work, in which case it will need to go in a new ticket.
Related to this, we will need to quantize interval timers as well. Not sure if we'll get that for free by quantizing time, or if it will be additional work. It probably will be additional work, in which case it will need to go in a new ticket.
On one hand, changes in Firefox 5 interval timer code to support "clamping" may make this easier. On the other hand, what about that same information coming from CSS animations: https://developer.mozilla.org/en/CSS/CSS_animations
Clamping does not help us. It is specific to nsGlobalWindow::SetTimeoutOrInterval().
DOMWorkers also have their own SetTimeout functions.
There are several different DOM events, each with their own implementation of the timeStamp field. They do not share a common implementation.
I think that if we're going to do it in the browser, we pretty much have to patch PR_Now(), or alter the code in about a couple dozen different places. It will be a big patch that is sure to generate conflicts...
I think we need to stay in JS land for this one. I'm going to guess that in JS-land, this will take a couple of days to repeatedly experiment with and test.
Trac: Summary: Tor Browser should provide JS with reduced time precision to Provide JS with reduced time precision Component: Tor Browser to TorBrowserButton Points: 16 to 10
Perhaps also quote Brendan Eich and tell him, that you know Tor is part of the answer, but you as Tor Browser developer still require the feature, because...
Might be useful to introduce your position in all upstream bug tickets so the answer won't be: use Tor.
This turned out to be easier to do than I expected. Also, given http://arxiv.org/pdf/1502.07373v2.pdf (Aka "The Spy in the Sandbox"), we may want to do this sooner rather than later (ie for 5.0a1).
Here's a patch that should make all JS clock sources and event timestamps have 100ms resolution, except for keypress events, which should have 250ms resolution: https://gitweb.torproject.org/user/mikeperry/tor-browser.git/commit/?h=bug1517. It also clamps internal usage of DOMHighResTimestamps to 1 microsecond, to avoid internal sidechannels and other leaks.
Note that this patch does not alter event delivery or interval timer invocation in any way, as I expect that altering event delivery and timer invocation will break more things (especially twitch games and video/animation) than simply messing with Javascript's notion of wall-clock time. I chose 100ms resolution because it seemed like a very large granularity while still being on the edge of human perception. We'll need to test this on a bunch of Javascript games, HTML5 animation sites, and lots of HTML5 video, but hey, at least that will be fun! :)
We'll also want to keep a close eye on this for ff38-esr, as I bet more events/time sources were added since FF31.
Here's a patch that should make all JS clock sources and event timestamps have 100ms resolution, except for keypress events, which should have 250ms resolution: https://gitweb.torproject.org/user/mikeperry/tor-browser.git/commit/?h=bug1517. It also clamps internal usage of DOMHighResTimestamps to 1 microsecond, to avoid internal sidechannels and other leaks.
Kathy and I reviewed this and the changes look OK. It is hard to say what might break though.
One question: do you know how the ToMilliseconds() and ToMicroseconds() calls inside xpcom/ds/TimeStamp.h are exposed to web content? Is ToSeconds() exposed as well? If so, we should also reduce the resolution of values returned by ToSeconds().
Here's a patch that should make all JS clock sources and event timestamps have 100ms resolution, except for keypress events, which should have 250ms resolution: https://gitweb.torproject.org/user/mikeperry/tor-browser.git/commit/?h=bug1517. It also clamps internal usage of DOMHighResTimestamps to 1 microsecond, to avoid internal sidechannels and other leaks.
Kathy and I reviewed this and the changes look OK. It is hard to say what might break though.
One question: do you know how the ToMilliseconds() and ToMicroseconds() calls inside xpcom/ds/TimeStamp.h are exposed to web content? Is ToSeconds() exposed as well? If so, we should also reduce the resolution of values returned by ToSeconds().
ToMicroseconds() is exported to content by window.performance.now(). I think ToMilliseconds the underlying call to obtain the timesource for nsDOMEvents (though at the moment I'm not 100% certain exactly what made me believe this, but some casual grepping shows that it is used everywhere in the codebase). I didn't touch ToSeconds() because its implementation is highly platform dependent, and it is only used in the animation code. It did not appear exposed directly to content.
I will verify all this with deeper inspection tomorrow.
I looked into this more, and noticed one case where ToSeconds() was exposed to content. AnimationFrame events have an elapsedTime field. I truncated that timestamp to millisecond accuracy (though in reality, the timestamps were varying by as much as 20ms for me).
I didn't see any other leaks to content by either ToSeconds or ToMilliseconds.. I pushed this to tor-browser-31.7.0esr-5.0-1 for 5.0a1 as commit dcd5fcc1.
Calling this 'fixed' for now, but I imagine we'll have a fun time testing everything and deciding what to do about breakage, and we'll want to revisit this for ff38-esr.
Trac: Status: needs_review to closed Resolution: N/Ato fixed
I looked into this more, and noticed one case where ToSeconds() was exposed to content. AnimationFrame events have an elapsedTime field. I truncated that timestamp to millisecond accuracy (though in reality, the timestamps were varying by as much as 20ms for me).
Hi Mike ... I'm 4 years late to the party... but I'm doing some "work" on some current (and open / unpatched) timing attacks - and the reason AFAIK is that 60fps = 16ms