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?
Why Are Inline Styles Bad For Accessibility? If styles are embedded directly into HTML elements using the style attribute, the HTML can become difficult to read (and thus maintain), resulting in accessibility issues for some visitors to your website.
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.
Ultimately, it's important in terms of inlining CSS and performance that you don't just dump all the CSS for your site into the head. If you inline too much, the performance implications will be worse than what you started with.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With