Didn’t you always want to know what your visitors are searching? And I don’t mean searching like what he typed into google, but what term(s) they try to find on your website (e.g. using Ctrl-F).
The idea is pretty straightforward: If you are searching something on a site, your browser will highlight what you are searching for (at least the first hit). So it has to somehow fiddle with the representation of the page. The shadow DOM seems to be presenting itself as a target for this one. For those who have never heard of this I recommend Glazkov (2011). In short it is a way to create and modify elements hidden in the DOM; frequently used by browsers to draw complex items like media player controls. After some reading, trying to find out what the API might be, I stumbled upon document.getSelection(). I didn’t really thought this would work, but in fact it does. Well, at least in Firefox. In Chrome the user has close the search widget to make the searched term available. And in Opera it doesn’t work at all. So what do I mean by “it works”?
Firefox highlights the search result on the page and handles it as a selection. This enables the site to have a look at what you are typing in your search field. But this raises one drawback. The getSelection method only works if the searched term can really be found within the document.
To solve this, a pretty straight forward approach sprung to my mind. I could just generate dynamic content providing all possible next inputs. So I basically generate a base set of printable characters and wait for the user to start his search. Then, as he is typing, I continuously check what the user has typed and append a list of strings to the document using the user’s term and postfix it with every printable character. As long as this happens faster than he is typing and he types consecutively, not changing letters within the search term or at the beginning, it works. Such problems could be tackled by generating more letters in advance and also add them within the words. But the general users behaviour should be covered.
A very simple proof of concept can be found here.
You might wonder by now why this is interesting at all. We have stored all our data at social communities and google knows everything we search for anyhow. This brings me to how I initially got the idea to have a look at this. Once again I saw a tweet about a hacked site, that I am registered at and the leaked accounts were presented at some random pastebin page. So I went there and did what? Of course, I searched for my email address, user name or whatever information might indicate that my account information got leaked and is now accessible for everyone else.
In this scenario, all they can find out is that I am the owner of that account I searched for. No harm done, except some privacy issues if combined with some more snooping. But what if an attacker generates user IDs on the fly based on what the lured user types? Thereby gaining new information about the victim’s user name at site XY or his registered email address, depending what information is presented to him in the fake leak.
This could be taken even one step further. The site could only present numerical user ids and corresponding passwords. Done as a targeted attack this could reveal the user’s password granted that he is careless enough to type his password into a search field of his browser. But the inhibition threshold is probably much lower, because you type it into your own browser not a search function of some site or a search engine.
For those of you who really had a look at the demo, probably two questions/remarks arise.
Second remark would be that the generated text is not very carefully hidden. Well, first I thought about leaving it completely default text and therefore easier comprehensible what is going on. But then again I wanted to make it at least somewhat less obvious. Sure with CSS or IFrames or whatever is up your sleeves you can hide it completely from the potential victim.
By the way this also works with Pentadactyl in Firefox and Vimium in Chromium, when searching by “/”. This makes Chromium users using Vimium more susceptible to such an attack.