27

A Content Security Policy with a default-src or style-src directive will prevent inline styles from being applied to <style> elements or style attributes. To allow the use of inline styles, a value of unsafe-inline must be applied to a CSP fetch directive. This seems to indicate that inline styles are unsafe.

While inline Javascript is an obvious attack vector for XSS attacks (CSP is pretty much useless with script-src 'unsafe-inline'), Google Web Fundamentals considers inline-styles to be a relatively equivalent threat, providing one example of a clever data exfiltration method from a 2009 blog post.

On the other hand, another Web Fundamentals article suggests that inlining styles can help optimize the critical rendering path, as first paint won't be blocked while the browser fetches external resource(s). It seems there is a very real tradeoff between security and performance:

In general, how risky are inline styles?

myconode
  • 2,518
  • 1
  • 26
  • 28
  • 3
    Not an answer, but if you want to see some examples of what *could* be injected using inline styles, I would check out [HtmlSanitizer's test suite](https://github.com/mganss/HtmlSanitizer/blob/master/test/HtmlSanitizer.Tests/Tests.cs). – Tieson T. Jan 29 '17 at 20:17

1 Answers1

21

From an is-an-exploit-possible point of view, then yes, inline styles are just as dangerous as inline JavaScript. However, exploitation of such vulnerabilities is much less common.

There are a handful of ways that CSS can be used maliciously, with the most common method being injection of images. There are (at least) two possible ways for that to occur:

div {
  background-image: url("evil.png");
}

img {
  content:url("evil.png").
}

Allowing the user to 'force' an image to render is incredibly dangerous, as you can use PHP to spoof the content of the image -- you can mine all sorts of information from someone who views a PHP image, such as their cookies, their browser, and even their operating system. What's worse is that the image will render correctly, so the person viewing the image won't even notice anything suspicious.

Consider other situations where a user is able to upload an image, such as setting a profile picture on a forum (that would ultimately become an <img>). The key lies in how the user is able to save the image so that another user would render it. For profile picture uploads, server validation usually prevents users from uploading files that aren't images, or are malicious images. It's almost impossible to validate images that are injected inline as background-image or content URLs.

In addition to this, we can even take that a step further, by telling the URL itself to run JavaScript:

url('javascript: eval(evil)');

As you can imagine, that allows an attacker to do almost anything they want.

There are also rarer methods of XSS, that even allow for things such as executing JavaScript directly with the behavior tag and HTC:

body {
  behavior: url(evilscript.htc);
}

It's also worth noting that use of a same-origin policy is exploitable in itself, so is not secure.

So essentially, while inline styles slightly improve speed, as you say, there is a definite trade-off between security and speed. Avoid inline styles wherever possible ;)

Hope this helps!

Community
  • 1
  • 1
Obsidian Age
  • 41,205
  • 10
  • 48
  • 71