Wednesday, February 27, 2013

URL detection with location.hash and history Timing attack. I know your Facebook username.

Meanwhile working hard on Pagebox. XHR proxy is done, looking forward your feedback

TL;DR there is a way to detect current URL in iframe or window by assigning it TRY_URL# - if our guess was right page wont be reloaded. Not very practical and pretty slow, but it's still a (minor?) vulnerability in standard.

UPDATE I found a better way - hash assignment changes history much faster than normal, "reloading" assignment - so we use a Timing attack to figure out if our TRY_URL == REAL_URL. Works for all websites quite reliably.

1) set data: url checker, you can postMessage some data to opener
2) redirect window to /redirector path which will redirect to /real_path
3) try to assign /try_path# and if it was equal real_path history object will be changed right away. So - execute history.go(-1) and see
4) if it redirects to data: - it means real_path != try_path. You can setTimeout for 100 ms and realize that you found real_path - history.back() will remove new #, not redirect to data: url
5) works for any website, https too. I demonstrate it on Facebook

I can't say this vulnerability is very major and severe. At some extent it's not a vulnerability, it's a common standard that will not be changed in the near future. Severity depends on what critical information is exposed in your URL.

Yes, the trick is perfectly legal but here I prove that it's a vulnerability!

  • location.hash can be used as data transport as well as and it's quite well-known. If you assing location=SAME_URL#new_hash for iframe/window location, where SAME_URL is current path - only hash will be changed, page itself will not be reloaded.
  • onload is not fired up if you change hash this way
  • redirect from path#hash -> new_path#hash adds #hash automatically to new path.
  • when you assign location=SAME_URL#SAME_HASH it won't be pushed to history object
  • blocked popup windows in Chrome are full-featured windows just running in background. They are not "blocked" at all.

The idea is — we simply can check if URL is equal to our TRY_URL by assigning location="TRY_URL#" and if onload event has been triggered - answer is "No". Otherwise some setTimeout can let us know that our TRY_URL was a right guess!

Theoretical showcase - sinatra app and ?id=95 path detection

Real world showcase... Facebook again, maybe?
I will detect your current username. Wait, I cannot use frames, FB has X-Frame-Options! And when we use we cannot set onload for cross origin windows. Too bad. But I didn't give up and used timing attack!

Here - very simple PoC telling if your real handle is equal TRY_HANDLE.


  1. I honesty don't understand. How is this a vulnerability?

    You can verify a "solution" to the user handle "problem" quickly, but you can't close in on one. This has no means of convergence.

    NP problems are polynomial-time verifiable. How is this different?

    Is my reasoning wrong here?

    1. i don't say it is quick, but it is a vulnerability. race condition. detection of URL.

      and FB is only showcase, I found a way to detect hash much faster - 3 hashes/second.
      not all vulns are major

    2. Also, heuristics for usernames are pretty easy. If someone knows your first name, last name and email address (common for web apps), there's a high likelihood they can guess your Facebook username because of conventions that most people follow.

  2. Although you have proven this leaks data which has not been granted by the client, I would not label it as an exploit. However - this should not have been possible, and could allow for companies to fingerprint who you are.

    A good find, no doubt. Please try to improve your way of writing, it is a bit hard to follow sometimes.

    1. > I would not label it as an exploit
      I think this is a vulnerability. Especially for privacy, if you apply it on more websites you will see what can happen.

      > Please try to improve your way of writing
      open for your ideas, I indeed not always properly explain.