Are there any dangers or security risks in allowing user css?
Sorry for unspecific question. Possible implementation: having a textarea for users to input custom css, and then taking that css and putting it into a style element: <style type="text/css"></style> with js.
Yes, there are many potential XSS attacks, mostly through putting JavaScript in urls for background-image and whatnot. Search for "style" in the XSS Cheat Sheet for some examples.
There is also the potential that the user CSS could break your site, for example making the navigation menu 0x0 pixels or moving it offscreen to -1000, -1000. Or the CSS itself could reference images from other sites, which you can't guarantee will continue to stay up.
That depends on how you implement that functionality. If you provide a form that allows people to select their own CSS values, then there's an inherent risk of dirty input.
All user input is dirty
What if they write some CSS that hides or obscures something like a login?
There are multiple issues as well, there is a CSS history hack, several XSS vulnerabilities related to url's, and probably more that haven't been thought of.
Always sanitize user input before displaying it on a page.
If the only user affected by the CSS is the user that provided the CSS, then there's not much of a risk. Any XSS vulnerability could only affect the user.
Some browsers allow users to use custom CSS anyway, or ignore it altogether, so I wouldn't consider it a problem.
Related
So. I'm a CSS amateur, and I'm dealing with an issue a bit above my experience.
Basically: we have a site with a third-party vendor. We cannot modify their stylesheet. I've been told we cannot forward the URL. We cannot unpublish the without deleting it, which is not an option. We cannot upload our own stylesheet. We cannot edit the page HTML beyond a small window. And we need to disable the the site-- specifically, login functions-- so users can't use it, and provide them a link to the new site.
tldr; If this sounds backwards and convoluted, please understand I'm just doing my best to work with a third-party that doesn't really have a lot of flexibility.
So far, I've done this by identifying the styles they have, and writing my own css to disable them (just setting everything to height:0px width:0px overflow:hidden has worked pretty okay) and inputting that into the text/html field they let me edit. Which, honestly, seems kind of like a design flaw that I can break any page as badly as I'm doing, but what do I know...
Problem: they have a login form in a table. No div or class associated with it. With no class/id, I can't style it through css. Styling "table" to height:0px, width:0px just, uh, blanks the whole page.
So, my question: how do I style a table with no class/id in CSS alone with no ability to add a tag to it?
And yes. I know what I'm doing is probably giving everyone reading it an aneurysm. I'm sorry for my CSS crimes.
You can target the said form trough some parent which will work until they either reposition the table outside that parent or fuck with something you used to target the parent.
To be more specific I need a HTML structure of the said page.
But generally let's say you find a parent with a class Parent and this is the only form (otherwise you have to say nth child of type form) inside that parent you can use .Parent>form { your CSS code}
This should expand options for you. Ideally find a parent somewhere that has id and hope its unique for site.
NOTE: Be very afraid when you target things like this, if you can't bind that to either that specific page or specific unique-for-site id parent, you risk somewhere being the one or multiple other match for your CSS selector, and since in most cases (unless you use CSS loader or have separate indexes including separate CSS files) you share same CSS to entire web page it will change them as well.
NOTE: Be even more afraid if you use CSS outside of it's domain - STYLING especcialy for security things, like giving access. This is a serious security violation if you only hide login elements. Anyone with a bit of knowledge can read the code and hide it on client and login. At least don't load then into DOM using display:none; instead visibility: hidden;
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!
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.
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.
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.