Tracking users that block cookies with a HTTP redirect
In essence this technique that I call “redirect tracking” works by abusing the HTTP 301 redirect mechanism to redirect each user to unique URL. HTTP 301 redirects are used by web-server to tell browsers that the requested URL is redirected “permanently” to another one.
This mechanism was first designed to allow website to correct user mistakes or redirect multiples domains to a single one. Nowadays the most prominent use of 301 redirects are shortening URL services.
For example when using the short URL http://bit.ly/na7YwZ to access this blog post the following interaction is taking place under the hood:
In the first step your browser requests from bit.ly the content of the short URL. Bit.ly answers by saying that this content is permanently located at the URL: . The browser caches this information and navigates to the redirected url.
How does it work ?
The “redirect tracking” method works almost the same way except it use the redirect to plante the unique identifier:
When the user request the tracking page, its code will look at the URL path/parameters to see if there is a unique identifier (i.e http://evil.com/track.php?id=xxx). If the URL does not contains a unique identifier (http://evil.com/track.php) then the tracking page uses the HTTP 301 headers to assign a unique identifier to the user (redirect to: http://evil.com/track.php?id=xxx). When the redirection occurs the browser will cache the redirect information so the next time the user connect to the tracking page the user will be redirected to the tracking page with his unique id.
I tested this technique on Firefox 5, Internet Explorer 9 , Safari and Chrome: it works on all of them except the new versions of Safari. There is a couple of interesting quirks to take into account while using this method:
- You need to add caching headers otherwise it won’t work on Firefox and Internet Explorer
- The only redirect code that works is the 301. Every others one is not cached.
- On Chrome and Firefox sometime the first redirect is not cached. I have no idea why. Opening a new tab seems to help.
- The technique used to work on Safari but does not to work on the new version. I don’t know when this changed. If you have an idea how to make it work on Safari let me know
- The redirect is cached even between browser restart so it is almost as reliable as a cookie.
If you want test by yourself a demo is available from here: http://elie.im/demo/redirect-tracking.php
IF you want to play with the code you can get it from here: http://elie.im/demo/redirect-tracking.phps
Thanks to Andrew Bortz: He was the first to research in a systematic way how to track user with a simple HTTP request and this technique was born from our discussion.