Is a cross-domain attack via stylesheet possible? - css

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.

Related

Will a JAWS script override a screen reader's ability to read the DOM?

I'm tasked with evaluating some legacy web pages (classic asp) for accessibility. You can assume the HTML is not perfectly formed and that it's loaded with inline javascript and that we make use of javascript libraries that vomit HTML to create dynamic features. It's a circus in there.
While I recognize that the obvious answer is to re-write the page(s), that's not an option in our given time tables. So I'm trying to find the best way to make the pages work with a screen reader. Here's what I think I know.
We can use JAWS scripting to instruct the browser how to read the page.
We can use ARIA attributes to give the pages better organization and structure.
Specifically, I'm trying to figure out:
Question 1) If a JAWS script is present, will it be used exclusively by the browser/screen reader and ignore any improvements I make in the underling HTML structure?
Question 2) Could some well-place ARIA attributes give the page enough structure so that the default screen reader properties will work in an acceptable manner (without a JAWS script).
Question 3) I suspect the tough answer is that I would need to do both, which I'm trying to avoid because we barely have the capacity to do just one. But we don't want to lose a customer, of course. :-(
Many thanks for any input.
Instead of explaining only to JAWS how to access your pages, use JavaScript to explain it to any Assistive Technology (AT) for the web. I expect the same effort, while it will profit way more users.
In a JAWS script you would need to describe ways to access DOM nodes that are not accessible. That would include
speaking out information that you have to find elsewhere on the page
adding keyboard navigation where it's missing
Both can be done in JavaScript, probably even easier (you'll need to address DOM elements).
What you will need to avoid is restructuring the DOM and changes to classes, since those are most likely used by the scripts that generate them.
But I'd expect that adding attributes and keyboard handlers will do no harm to the existing scripts. Beware of already existing handlers for focus or keyboard events, though.
I would recommend making a list of attributes and handlers you suspect to conflict with the existing scripts, and searching the scripts for these, like onkeypress or onfocus event handlers.
The absolute best way to make your application/site accessible is to use semantic HTML. It doesn't matter if that HTML is generated by asp or jsp or whatever.
If you have a table, use a <table>.
If you have a heading, use an <h2>.
If you have a list, use a <ul>.
Use <section>, <article>, <nav>, <aside>, <header>, <footer>, etc
That's how you create structure on your page that a screen reader user will appreciate.
If you can't use native HTML, then fall back to ARIA, but treat it like salt. A little bit greatly enhances the flavor but too much spoils the meal.
If you can't use a native <h2>, then make sure you use the appropriate role and attributes.
<div role="heading" aria-level="2">this is my custom h2</div>
If you can't use a native <header>, then make sure you use the appropriate role and attributes.
<div role="banner">my header stuff goes in here</div>
I would recommend totally forgetting about JAWS scripts. It doesn't matter if that's what the customer thinks they should focus us. It's not about that customer. It's about that customer's customers. The end users. They should be able to use whatever screen reader they are used to using and most comfortable with. That's the whole purpose of accessibility - making the site usable and accessible by as many people as possible using whatever assistive technology they are used to using.
Following the Web Content Accessibility Guidelines (WCAG) will lead you to that result.

How can I allow user controlled CSS without introducing XSS?

I have an application where I could customize HTML templates depending on requirement of client. It has a provision of including CSS style scripts when creating a template which would be injected at the end when generating the template. By this way, client/support person could dynamically generate variety of HTML templates.
But when I give this project for a security scan, all the CSS injections are detected as security vulnerabilities (XSS Injections). My Application itself designed based on the CSS injection as it is required to create dynamic HTML template without the involvement of a developer.
Is there a way to prevent XSS security flaws at the same time of achieving application's end result?
Please let me know if there is an alternative way of doing this.
Allowing untrusted CSS input is an XSS flaw as it could be used for redressing the UI. For example, a malicious user could make their text and content appear to be authoritative text coming from the website itself by dressing it with the same style and positioning.
See the Google Browser Security Handbook for more information.
There are also ways to get script to run via CSS:
The risk of JavaScript execution. As a little-known feature, some CSS
implementations permit JavaScript code to be embedded in stylesheets.
There are at least three ways to achieve this goal: by using the
expression(...) directive, which gives the ability to evaluate
arbitrary JavaScript statements and use their value as a CSS
parameter; by using the url('javascript:...') directive on properties
that support it; or by invoking browser-specific features such as the
-moz-binding mechanism of Firefox.
Script execution via -moz-binding is available on Firefox 2 and 3. The Google Browser Security Handbook doesn't appear to have been updated since Firefox 3. This post indicates this is now fixed so that the XML file has to be readable from your own domain. XBL doesn't seem to be possible in current versions of Firefox.
In Internet Explorer 10 and earlier HTML Components allow script execution in CSS.
You can mitigate the risk of untrusted content by implementing an HTML5 sandbox. Also consider implementing a Content Security Policy with sanitisation to prevent users from escaping from your CSS context in any way (I haven't seen your code, but I wonder if a user enters </style> as part of the CSS, whether it allows them to escape the style tag?).

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

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.

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.

User Uploaded CSS safe?

Is there anything tricky someone could do with user-uploaded CSS to harm a site? If I wanted to allow users to upload/share their own CSS themes to a site, is there anything I should look for or disallow?
EDIT: Assume I know how to check if it's a valid CSS file etc. I'm looking for CSS specific exploits I need to avoid.
I believe standard CSS, parsed in a standard way is safe. However, through various non-standard extensions CSS is unsafe.
It's not just CSS that is unsafe, due to the fact that some browsers ignore RFC 2616 and sniff the content type instead of respecting the Content-Type header, it is possible to trick some browsers into embedding JavaScript hidden within static image files.
Even if you work around these particular issues, there's nothing stopping browser vendors from screwing you over in other ways without you realising.
As a general rule, I would not allow untrusted users to upload files unless I gave each user their own subdomain and ensured that any cookies on the main site were limited to the www host. This makes it look to the browser that each user has their own separate site with their own separate security context, so even if they manage to execute code, it doesn't compromise anything.
Even if you parse the file for valid CSS a hacker could still be malicious by using something like :before and :after. To ensure security you will want to whitelist a subset of css properties & selectors in your validation.
They can include an .htc file which is essentially Javascript. Actually, it doesn't even need to be in .htc file, you can write Javascript in CSS using expression(). And also (although this is given), they can mess with your site by hiding/showing stuff inappropriately.
You primarily need to be careful on what is being uploaded. If you do some kind of sanity check, that it is valid CSS, you should be fine, but if you just allow any old file to be uploaded, someone could sneak in some java script or other malicious code.
The actual type is not harmful, but the whole upload concept is the problem as it allows attackers to deliver a payload you wouldn't expect.
But I would say as long as you check off your security checklist and validate your content to be at least some css, you should be fine.

Resources