CSP style-src: 'unsafe-inline' - is it worth it? - css

Currently I'm using Modernizr on all my sites and it turns out because of how it works it requires unsafe-inline styles to be allowed. I am already not allowing inline scripts and unsafe-eval for scripts. Curious as to what security risks there are for allowing inline styles?

Allowing inline styles makes you susceptible to a the "other XSS". Cross Site Styling attacks.
The idea here is that any places where a user can inject a style attribute into your document they can modify the appearance of your page any way they want. I'll list a couple potential attacks ordered by increasing severity:
They could turn your page pink, and make it look silly.
They could modify the text of your page, making it look like you're saying something offensive that could offend your readership audience.
They could make user generated content, like a link they provided appear outside of the normal places where people expect to see user content, making it appear official. (eg, replacing a "Login" button on your site with their own link).
Using a carefully crafted style rules they could send any information included on the page to external domains and expose or otherwise use that data maliciously against your users.
The fourth example, with the information being leaked to external domains could be entirely prevented in spite of the unsafe-inline provided you ensure your other CSP rules never allow any kind of request to go to a untrusted or wildcard domain. But the first 3 will always be possible if you miss blocking a style attribute somewhere.
Mike West did a good talk on this for CSSConf a few years back for some more examples.

Personally I find not using unsafe-inline for CSS is impractical. It means I have to use an external style sheet file for EVERY style. Coloring text, centering text etc. It can be done. You can do this by using a main style sheet "main.css" and a file sheet for every page ("index.css", "contect.css", etc). However I am not so stupid that I allow arbitrary code execution; I filter out all less then and grater then signs. I find this to be an unreasonable restriction. Blocking inline JavaScript is not as bad as blocking inline CSS. I can see blocking inline JavaScript. However I don't think I will do that ether. If you are careful to filter your less then and grater then signs (there are some other stupid things you can do besides not filtering these) if you don't make stupid mistakes that allows arbitrary code execution then you are safe. These inline blocks are only created to protect web developers that screw up there code in a way that allows arbitrary code execution. But the blocks make it a bit harder to code. So it's a trade off.
TLDR IMHO not worth blocking inline CSS, worth blocking inline JavaScript but unnecessary. I will NOT consider blocking inline CSS, I am not going to block inline JavaScript but I might consider it.
Experience: I am a web designer that designs in code using HTML CSS JavaScript and PHP. I have my own website that I coded by hand. And I validate with the official w3 validator. I keep up with web design standards like HTML5.

Related

What are the risks associated with using inline styles?

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?
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!

Custom CSS security

I'm doing work on a website, and a user can create a custom CSS stylesheet. I understand that there will always be a danger in this, but is there any way that I could make my validation more secure? I'm using this:
$customCSS = $_POST["submittedCustomCSS"]; //put user's submitted stylesheet into variable
$customCSS = htmlspecialchars($customCSS); //hopefully validate it?
file_put_contents("../custom.css", $customCSS); //save user's stylesheet
The page the custom CSS is displayed on is PHP-enabled, and the CSS is shown through <link rel="stylesheet" href="<?php echo $postID; ?>/custom.css">
Is there any way to make this more secure? Thanks in advance! :)
htmlspecialchars($customCSS); //hopefully validate it?
No, this is not sufficient. This may stop the CSS from escaping a </style> element in which it is embedded, but does nothing to prevent the CSS from styling arbitrary elements on the page, or from loading custom fonts or from abusing other problematic features of CSS whose security implications are still poorly understood.
If a custom stylesheet can be applied to any page that it's author cannot access, then you need to be significantly more strict than this. There are ways that custom stylesheets can be exploited to steal data like Credit-Card numbers or XSRF tokens that don't need to run JS.
For example, if one user can elect to use another user's custom stylesheet, then that could lead to a security vulnerability, and you should not require users to be able to read and vet a CSS file to use features of your site safely.
"Scriptless Attacks – Stealing the Pie Without Touching the Sill" explains some of the ways injected CSS can be problematic:
We show that CSS markup, which is traditionally considered to be only
used for decoration/display purposes, actually enables an
attacker to perform malicious activities.
...
We introduce several novel attacks that we call
scriptless attacks, as an attacker can obtain the credit card
number by injecting markup to this page without relying on
any kind of (JavaScript) code execution.
...
Neither of the discussed attacks depends on user interaction
on the victim’s part, but uses a mix of benign HTML, CSS
and Web Open Font Format (WOFF [23]) features combined
with a HTTP-request-based side channel to measure and ex-
filtrate almost arbitrary data displayed on the website.
Because Microsoft added CSS expressions as a proprietary extension to Internet Explorer, handling untrusted CSS securely is more complex than simply encoding it correctly. To do this properly you need to parse the CSS then only output things matching a whitelist. Unless you do this, it's trivial to inject JavaScript into the page for Internet Explorer visitors.
An alternative approach would be to only accept valid CSS, however I'd be concerned that Microsoft might try to sneak something in inside comments or something like they did with HTML.

Is a cross-domain attack via stylesheet possible?

I need to implement a flexible styling system for web pages that are created by users of my web application.
Ideally I would like to allow them to use CSS. Is linking to a style sheet at a user defined url a Bad Idea? Why? Is it possible to do this safely?
What would your approach to this be? I am trying to avoid building a style 'editor'. Though using an off the shelf one might be an option, suggestions?
Is it possible to do this safely?
Depends on how you define "safely". An external style sheet could make things look ugly, or play shenanigans with existing control elements on the site. You won't be able to prevent that as it's going to be impossible to detect. Here is a nice overview of malicious things one can do that way.
Also, obviously, CSS can trigger requests to any kind of URL by setting a background-image or similar. The browser will notice if the URL is not a valid image resource but the request will always happen. This way, one could provoke a password prompt to come up that the site's user may mistake for his own login prompt.
I'm not aware of any scripting attack vectors through CSS, although I'm pretty sure that IE's behavior could be one. I would definitely strip out those.
There is a related question on Stack Overflow but none of the vulnerabilities pointed out in the accepted answer works with pure external style sheets.
Yes. It can be a vector. This bit livejournal.
LiveJournal contains a flaw that allows a remote cross site scripting attack. This flaw exists because the application does not validate CSS style attributes in the '/cgi-bin/cleanhtml.pl' script before being saved. This could allow a user to create a specially crafted URL that would execute arbitrary code in a user's browser within the trust relationship between the browser and the server, leading to a loss of integrity. Read more at osvdb.org/21896
Caja's Attack Vectors Wiki explains how expression and moz-binding and similar mechanisms can allow arbitrary code execution.
Effect
Crafted CSS stylesheets can execute unsanitized javascript in the global scope on some browsers.
...
Versions
IE 5 and later (but not IE 8 or later in "standards mode").
Mozilla/Firefox, versions not known.
Example
<div id='oDiv' style='left:expression(alert("hello"), 0)'>
Example DIV
</div>
node.style.cssText = 'left:expression(alert("hello"), 0)';
<input style='-moz-binding: url("http://www.mozilla.org/xbl/htmlBindings.xml#checkbox");'>
div {
-moz-binding: url(data:text/xml;charset=utf-8,%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cbindings%20id%3D%22xbltestBindings%22%20xmlns%3D%22http%3A//www.mozilla.org/xbl%22%3E%0A%20%20%3Cbinding%20id%3D%22xbltest%22%3E%3Ccontent%3EPASS%3C/content%3E%3C/binding%3E%0A%3C/bindings%3E%0A);
}
node.style.MozBinding = 'url("http://www.mozilla.org/xbl/htmlBindings.xml#checkbox")';
<ul>
<li style="behavior:url(a1.htc) url(a2.htc)">List Item</li>
</ul>
Is it possible to do this safely?
Yes. You can white-list CSS properties and strip out any you don't judge to be safe.
Caja defines white-lists in JSON format that allow a large subset of CSS to be used while banning those that might execute code.

Do additional, unused CSS definitions slow down browsers?

After working with many CMSes and cutting up many HTML designs, when I saw SilverStripe's use of CSS, I was converted.
Essentially, that it would be a waste to change IDs in <div> tags depending upon the page you were on, and that changing the <body> tag's classes and ID would be an easier way of changing specific pages.
Such convictions were brought into question by a coworker during the following problem:
On a specific website, we have a variety of pages that are similar in structure. Some may include a special form, and some may not. All special forms should have a different background image depending upon the sub-section we are in.
Due to a claim that "additional lines of CSS slow down body.onLoads," my argument to code all background expectations in the CSS was rejected.
Can anybody cite evidence between a variety of cases? Cases including: Badly-coded CSS, and CSS well-coded, but having a variety of unused CSS on each page?
(And specifically speaking on my problem, can anybody explain my unease? I feel uncomfortable assuming images will be there and auto-generating Inline CSS (or header-section-based style tags) based upon a variable from a database.)
It's not going to matter (noticeably) unless your website is Gmail or YouTube (or is similarly CSS heavy).
Google has some recommendations in their Page Speed guide:
http://code.google.com/speed/page-speed/docs/payload.html#RemoveUnusedCSS
Removing or deferring style rules that
are not used by a document avoid
downloads unnecessary bytes and allow
the browser to start rendering sooner.
Before a browser can begin to render a
web page, it must download and parse
any stylesheets that are required to
lay out the page. Even if a stylesheet
is in an external file that is cached,
rendering is blocked until the browser
loads the stylesheet from disk. In
addition, once the stylesheet is
loaded, the browser's CSS engine has
to evaluate every rule contained in
the file to see if the rule applies to
the current page. Often, many web
sites reuse the same external CSS file
for all of their pages, even if many
of the rules defined in it don't apply
to the current page.
The best way to
minimize the latency caused by
stylesheet loading and rendering time
is to cut down on the CSS footprint;
an obvious way to do this is to remove
or defer CSS rules that aren't
actually used by the current page.
Concerning this:
Due to a claim that "additional lines
of CSS slow down body.onLoads," my
argument to code all background
expectations in the CSS was rejected.
The extra time is in the order of a few milliseconds. Do what is easier and maintainable, not what is more "efficient".

Does a long internal stylesheet affect SEO?

I'm building a site with a lot of similar css between pages. I've decided that a good approach would be to have the css generated as strings by php functions (with parameters) and outputed as an internal stylesheet in every page that i serve. The benefits:
this way if i make a change it will reflect throughout the entire site without having to maintain duplicates
i can send only the necessary css for a certain page
it's better than having small css files and sending a lot of css headers at inclusion
the possibility that the content might be displayed before the stylesheet is loaded is gone
i can calculate dimensions by using parameters
i can create a layer that will minify the result received from these functions or serve cached minified css
I haven't seen this done anywhere else unfortunately so i'm thinking that this might be because of SEO. The generated internal stylesheet will be at around 15kb max (before minifying the stylesheet).
I need your opinion on this approach and your thoughts about the impact a long internal stylesheet will have on SEO.
Many thanks.
Not an answer to your question (which is interesting enough!), but most of your arguments for inline CSS are wrong. An external style sheet is always the better and faster solution.
The first point you can handle by adding a version number to the style sheet's file name
The second point is moot because an external file gets cached, so no additional requests
The third point is moot for the same reason
The fourth point won't really matter once the style sheet is cached
The fifth point can be sorted using inline CSS for only the properties that need to be
updated dynamically - usually a tiny fraction of the whole CSS code base
The sixth point I don't get.
Go for an external style sheet. Just make sure it gets served with the correct caching headers!
Like long blocks of inline JavaScript, they are ignored.
Bots look at the content, not the layout. If you want a better representation of what they see, try the Lynx browser.
Unfortunately they will not be cached on the user's browser either, as external CSS and JS are, making each page load slower. It is actually more efficient to have a large external stylesheet than server up related "css snippets" with each page.
Assuming by 'internal stylesheet' you mean inline CSS included using the <style> tag, I'd recommend against this. If you use an external stylesheet, visitors download it once on the first request, and it will then be cached. By including all of your CSS inline, you're adding page weight to every single HTML request.
Although it might seem more efficient to just serve CSS for the current page, or split your CSS into lots of different page-specific stylesheets; in practice it's usually better just to have one stylesheet. Serving this compressed and with appropriate expires headers will almost always be faster than the alternatives.
Regarding SEO, robots ignore CSS, so this won't have any affect. If you had so much CSS that it substantially slowed down loading of your page, in theory you might start having issues, but you would need an inhuman amount of inline CSS before this could even potentially be an issue.
To the extent of my knowledge, your CSS sheet plays a minimal role in SEO, what is more important is your HTML markup and execution.
Following the order of '< h1 > - < h5 >' for your heading tags, with accompanying '< p >' tags instead of '< font >' or similar approaches is what will effect a web crawlers ability to recognise and prioritise the content in your page.
While you can use CSS to hide paragraph that you only want to appear in search engines and similar techniques it has little importance compared to the HTML structure.
All benefits you said apply. Search engines doesn't care too much about CSS and javascript (of course, if your page takes too long to wrap and send, this will affect, but I don't think it is the case).
I've seen this kind of solution before, but people tend to avoid use scripting to serve, once you can use media queries instead, writing just only one external stylesheet. I think you should take a look on this.
However, I see you are trying to optimize the CSS sent. This is good, but talking about 80k for all sheets, makes me think if you are not over complicating the rules.
Well, as last opinion, you can cache many different responses and make use of "canonical" thing on page head.

Resources