Abusing HTTP status codes to deanonymize web users

Hey,

Back in 2006, RSnake (Robert Hansen) and Jeremiah Grossman have discussed a
new login detection technique(see:
https://webcache.googleusercontent.com/search?q=cache:ha.ckers.org/blog/20061108/detecting-states-of-authentication-with-protected-images/&strip=1
and
http://jeremiahgrossman.blogspot.com/2008/03/login-detection-whose-problem-is-it.html).
And in summary, using the "onerror" and "onload" event handlers along with
an authenticated HTTP resource such as an image or a js/css file, one can
detect if a user is currently logged into a given web application or not,
for instance:
<img src="http://example.com/users/authenticated.jpg" onload="alert('Logged
In') onerror="alert('Logged out')">

This has been known for a while and has even been researched over and over
again, but what brings this issue back into action is something I came
across recently, which is that almost all the major web apps out there
-especially social networks- were(and still are) vulnerable to user
deanonymization attacks using a variation of this technique. In brief, by
sending a "GET" request to a user-specific endpoint, something like (
http://example.com/user/1001/settings) or (
http://example.com/delete?userID=1001), One can detect if the current user
is a particular user or not by checking whether an error status code gets
returned from such request or not, given that if the current user is NOT
the user whose ID is "1001", those endpoints will typically return one of
these HTTP status codes (403, 404 or 500), which will eventually trigger
the "onerror" event handler. Moreover, A 302 HTTP status code may get
returned redirecting the user to a login page in case of that the user is
not logged in currently. Now we can exploit such behavior to detect not
only if the user is logged in or not, but also if he's a specific user or
not, here's a simple proof of concept I wrote while investigating this
issue:
-----------------
<script>
var x=0, y;
document.onreadystatechange = function (){
if(document.readyState == "complete"){
if(x==0 && y==1){
alert("This is the targeted user whose ID is 1001")
}else{
alert("The user is either logged out or NOT the targeted user")
}}}
</script>
<script src=http://example.com/user/1001/settings onerror="javascript:x=1">
</script>
<script src=http://example.com/user/0/settings onerror="javascript:y=1">
</script>
-----------------
P.S: Note that this actually demonstrates a real world example and many
applications out there are vulnerable.

The question that comes to mind here is whether this is a problem for web
authors to deal with or for browser vendors, and if it turns out to be the
problem of browser vendors, can this be fixed without actually breaking the
web? I'm not sure, but these are some solutions that do break the web:
[*]Not to send cookies with cross-origin requests, but this will break many
things, from web analytics services to social plugins..
[*]Disallowing such event handlers when it comes to cross-origin requests,
however this will break many legitimate use-cases, and it's somewhat a
common functionality on the web.

...Any thoughts?

Received on Friday, 8 May 2015 02:25:04 UTC