Tor Browser
The ability to privately communicate through the internet is very important for dissidents living under authoritary regimes, activists and basically everyone concerned about internet privacy.
While the TOR network itself provides a good level of privacy, making difficult or even practically impossible to discover the real I.P. address of the tor users, this is by no means enough to protect users privacy on the web. When browsing the web, your identity can be discovered using browser exploits, cookies, browser history, browser plugins, etc.
Tor browser is a firefox browser preconfigured and modified to protect user privacy and identity while browsing the web using TOR. Browser plugins are disabled, history and cache aren’t persistent and everything is erased after closing the browser, etc.
The user fingerprinting problem
While preventing users IP address to be disclosed is a key aspect for protecting their privacy, a lot of other things need to be taken into consideration. Tor browser is preconfigured to prevent a lot of possible attacks on user privacy, not only the communications layer provided by tor itself.
One common problem that tor browser tries to address is user fingerprinting. If a website is able to generate a unique fingerprint that identifies each user that enters the page, then it is possible to track the activity of this user in time, for example, correlate visits of the user during an entire year, knowing that its the same user.
Or even worse, it could be possible to identify the user if the fingerprint is the same in tor browser and in the normal browser used to browse internet. It is very important for the tor browser to prevent any attempt on fingerprinting the user.
In the past, a lot of fingerprinting methods has been used and proposed and tor browser has been updated with countermeasures. Examples of that are reading text sizes out of a canvas element, screen dimensions, local time, operating system information, etc.
One famous example of browser fingerprinting was Canvas fingerprinting. As of today, almost everything that can be used to identify the user has been disabled in tor browser.
UberCookie
During the last weeks I have been able to fingerprint tor browser users in controlled environments and I think it could be interesting to share all the findings for further discussion and to improve tor browser.
All the provided fingerprinting methods are based on javascript (enabled by default in tor browser as of today). I have created a quick and dirty PoC called UberCookie available as a demo here:
Measuring time
One interesting countermeasure for fingerprint implemented in tor browser is that javascript Date.getTime() (unix time) only updated each 100ms. So you can’t measure events happening under 100ms. This is useful to prevent a javascript inside a webpage to measure events in order to fingerprint the user. Since for some of the things I wanted to try needed better time accuracy than 100ms, this was the first thing to bypass.
There are a lot of ways to measure times smaller than 100ms using javascript in tor browser, some are obvious, or ther are intersting.
The first one I implemented was simply increment a variable by 1 each millisecond using setInterval. Even if the precision is not at milisecond level, is extremly better than the 100ms accuracy provided by Date.getTime.
Another way you can use to measure time is to create an animation in CSS3, configured at 1ms interval and listen to the animationiteration event.
However, the better accuracy I could achieve was using setInterval incrementing inside a webworker.
Mouse wheel fingerprinting
The mouse wheel event in Tor Browser (and most browsers) leaks information of the underlying hardware used to scroll the webpage. The event provides information about the delta scrolled, however if you are using a normal computer mouse with a mouse wheel, the delta is always three, but if you are using a trackpad, the deltas are variable and related to your trackpad and your usage patterns.
Another leak in the mouse wheel, is the scroll speed that is linked to the configuration of the operating system and the hardware capabilities itself.
I have created a little experiment as a proof of concept, available here:
Mouse wheel information leak demo
This demo creates three graphs, one with the scrolling speed, another with the scrolling delta, and another one with the number of times the user scrolled in the red box.
Mouse Speed fingerprinting
Another interesting fingerprint that could reveal some entropy is the speed of the mouse moving acrross the webpage. Since the speed of the mouse is controlled by the operating system and related to hardware, and can be read using javascript if you can measure time using the mentioned strategies.
It could be interesting also to measure average mouse speed while the user is in the page moving the mouse.
CPU Benchmark fingerprinting
With the improved accuracy on time provided by the setInterval inside the WebWorker, it is easy to create a CPU intensive script (or even memory intensive) and measure how long it takes for the user browser to execute it.
I have done some tests with different computers, getting completely different results, all of them using the same tor browser version.
getClientRects fingerprinting
The most intersting fingerprinting vector I found on Tor Browser is getClientRects. Is strange that reading back from a canvas has been prevented but simply asking the browser javascript API how a specific DOM elements has been drawn on the screen has not been prevented or protected in any way.
getClientRects allows to get the exact pixel position and size of the box of a given DOM element. Depending on the resolution, font configuration and lots of other factors, the results of getClientRects are different, allowing for a very quick and easy fingerprinting vector, even better than the canvas fingerprinting that is fixed.
Example of getClientRects on the same page with same Tor Browser version on different computers:
Computer 1:
Computer 2:
As you can see, there is a lof of difference in the results of getClientRects between two computers using the same tor browser on the same page and on the same DOM Element.
Results
An example of running ubercookie PoC in one computer (computer 1):
Client rects: {"x":131.5,"y":462,"width":724,"height":19,"top":462,"right":855.5,"bottom":481,"left":131.5}
scrolling milis: [2,2,0,3,0,1,0,2,3,0,0,3,1,2,2,1,2,1,4,4,35,2,1,3,0,1,0,3,0,1,0,3,0,1,0,3,1,0,3,1,3,0,1,3,2,4,4,8,44,4,1,4,4,405,2,3,2,1,3,1,3,57,2,0,2,2,0,2,2,4,60,2,0,2,2,0,2,2,6,54,2,2,2,0,2,1,4,8]
scrolling deltas: [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
Biggest mouse step: 65
In a few seconds, the result of the CPU benchmark will appear, please wait...
CPU Mean: 3245
And the result of running it in a different computer (computer 2), same Tor browser version:
Client rects: {"x":159.51666259765625,"y":465.25,"width":664.6500244140625,"height":18.449996948242188,"top":465.25,"right":824.1666870117188,"bottom":483.6999969482422,"left":159.51666259765625}
scrolling milis: [0,3,0,2,2,2,2,0,3,0,2,1,2,2,1,3,1,1,4,1,2,1,1,3,1,2,2,3,2,5,3,3,5,3,0,0,2,0,2,0,1,1,0,2,0,3,2,1,1,3,1,3,2,3,1,3,2,2,2,2,0,2,3,2,2,2,244,0,2,1,2,1,3,2,0,2,0,1,2,1,0,2,0,3,1,0,2,1,1,1,2,1,1,1,1,1,1,2,2,1,2,2,2,2,1,4,2,2,2,2,2,4,2]
scrolling deltas: [3,0.975,1.65,1.5,1.725,2.25,2.775,2.4,3.15,3.375,3.975,3.675,4.35,4.95,5.625,5.55,5.25,5.25,4.2,6.3,9.975,13.95,7.575,6.9,2.85,5.925,8.85,0.9,4.425,3.675,4.725,2.625,2.4,5.475,2.625,3.675,5.4,5.775,7.275,6.975,8.175,9,8.475,3.45,2.475,2.25,0.6,1.8,11.1,8.4,8.475,8.1,7.5,6.375,8.175,4.95,4.8,4.275,3.525,3.375,1.125,2.7,2.175,1.95,1.65,1.2,1.05,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
Biggest mouse step: 40
In a few seconds, the result of the CPU benchmark will appear, please wait...
CPU Mean: 4660.5
It is evident that the getClientRects are completly different, providing an interesting fingerprinting vector. The scrolling speed (milis) is also different. The scrolling deltas are very different, because of hardware differences. The mouse of computer 1 is faster, as you can see in ‘biggest mouse step’. The CPU benchmark provides different results, computer 1 being faster than computer 2.
Conclusion
It is easy to fingerprint users using tor browser to track their activity online and correlate their visits to different pages. getClientrects provides a very interesting vector for fingerprinting TOR Browser users. The CPU benchmark and the Mouse wheel and mouse speed methods provide even more information to distinguish between similar users.