Allowing user specific css templates - asp.net

I would like to have user customizable look and feel options on a website. I envision an interface for selecting background and text colors, images, fonts, etc.. I'm just not sure what the best way to store and use the information is. I plan on storing all options in a database table tied to the user.
Is there a good way to dynamically generate css for each user? Is it better to generate the css as they make changes and just store it, or to regenerate it for each page view? Are there established patterns for doing this kind of thing?

Separate out the parts of the CSS that are customisable from the parts that are static. That way you can still serve most of the CSS as you normally would.
Dynamically generate the CSS that is customisable. Don't try to do any optimisation or fancy caching unless you observe there's a performance problem.
The only potential performance problem is that the browser can't cache the customisable CSS. However, you probably don't want the browser to cache it anyway as that could mean that the user's colour scheme doesn't immediately update when they edit it.
If you do have a performance problem I wouldn't worry about ETags. ETags are designed to save the browser from re-downloading a component that it already has, but the customisable portion of the CSS is likely to be very small.
In case of a performance problem, consider inlining the customisable CSS directly into the HTML page. That will save an extra HTTP request. However, don't do this unless you are sure there is a need.

First of all, use appropriate caching headers for generated CSS and also use ETag header to re-validate CSS source when client asks for it. You must implement some fast ETag calculation algorithm, for example increment version field each time users changes some setting and return its value as ETag. In this scenario you may choose not to "generate the css as they make changes and just store it" but "regenerate it for each page view", because actually CSS will be stored in user agent cache and even when user presses F5 ETag will be used to ensure that CSS on client side is still valid.
Of course, CSS must be returned by some http handler (usercss.ashx or something like this). When including link to this CSS into HTML page, make sure to add some parameter to work around cached content issues, for example `
From my own experience I'd recommend you to use handler to serve user CSS as separate resource and do not embed it into HTML page each time it is generated, because in last case you must either recalculate CSS every time page is generated or somehow cache it on the server, both cases are rather bad ideas. Besides, this CSS may be rather large, there is no reason to download it on every request.

Related

What are the implications of a cached CSS file?

Specifically, does the browser cache only the text content of the stylesheet — so it doesn't have to fetch it again from the network — or does it also cache an internal representation it has of the contained CSS rules after parsing, so neither fetching nor parsing of a cached file is necessary?
If only the text content is cached, what are the benefits of caching a stylesheet over inlining it (where it cannot be cached)?
Caching is aimed at reducing load time by replacing the typically slow network download with the typically fast local file reading. As such, is a generic solution (you can cache any kind of asset, from HTML to CSS, JavaScript, PDFs, Excel...) and it can accomplish great time savings (normally seconds, even minutes for really slow networks). It also plays well with dynamic HTML.
What you propose is a very specific caching solution for a very specific data set (the nodes of an HTML document together with the CSS rules that apply to them) that typically needs milliseconds to process and can be continually changing thanks to JavaScript. It looks really difficult to implement, it'll be confusing for dynamic sites (when a page loads, everybody expects to get the initial HTML state, not whatever you were doing last time) and there's hardly any benefit on it. I'm not aware of any browser that has even tried it. There're certainly JIT compilers for JavaScript code, but nothing remotely similar to this.
If only the text content is cached, what are the benefits of caching a
stylesheet over inlining it (where it cannot be cached)?
I'd say cache itself is a valid benefit, isn't it? Generating inline CSS means more work for the webmaster (you either need to write server-side code that injects CSS files or enjoy the maintenance mess of not even having them). It also increases the size of HTML documents.

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.

Combining CSS files: per site or per page template?

We all know that we're supposed to combine our CSS into one file, but per site or per page? I've found pro's and cons to both.
Here's the scenario:
Large site
CSS files broken out into one file for global styles and many for modules
Solution A: Combine ALL the CSS files for the whole site into one file:
Best part is that the one file would be cached on every page after the initial hit! The downside is that naming convention for your selectors (classes and id's) becomes more important as the chance for a namespace collision increases. You also need a system for styling the same module differently on separate pages. This leads to extra selectors in your CSS which is more work for the browser. This can cause problems on mobile devices like the iPad that don't have as much memory and processing power. If you're using media queries for responsive design, you're troubles compound even further as you add in the extra styles.
Solution B: Combine one CSS file per page template:
(By page template I mean one layout, but many different pages, like an article page)
In this scenario, you lose most of the issues with selecting described above, but you also lose some of the cache advantages. The worst part of this technique is that if you have the same styles on 2 different page templates then they'll be download twice, once for each page! For instance, this would happen with all your global files. :(
Summary:
So, as is common in programming, neither solution is perfect, but if anyone has run into this and found an answer I'd love to hear it! Especially, if you know of any techniques that help with the selector issue of Solution A.
Of course, combine and minify all the global styles, like your site template, typography, forms, etc. I would also consider combining the most important and most frequently used module styles into the global stylesheet, certainly the ones that you plan to use on the home page or entry point.
Solution B isn't a good one: the user ends up downloading the same content for each unique layout/page when you could have just loaded parts of it from the last page's cache. There is no advantage whatsoever to this method.
For the rest, I would leave them separate (and minified) and just load them individually as needed. You can use any of the preloading techniques described on the Yahoo! Developer network's "Best Practices for Speeding Up Your Web Site" guide to load the user's cache beforehand:
Preload Components
By preloading components you can take advantage
of the time the browser is idle and request components (like images,
styles and scripts) you'll need in the future. This way when the user
visits the next page, you could have most of the components already in
the cache and your page will load much faster for the user. There are actually several types of preloading:
Unconditional preload - as soon as onload fires, you go ahead and fetch some extra components. Check google.com for an example of how a
sprite image is requested onload. This sprite image is not needed on
the google.com homepage, but it is needed on the consecutive search
result page.
Conditional preload - based on a user action you make an educated guess where the user is headed next and preload accordingly. On
search.yahoo.com you can see how some extra components are requested
after you start typing in the input box.
As far as the conflicting selectors go: combining all the files and doing it any other way should not make a difference, this is a problem with your design. If possible, have all modules "namespaced" somehow, perhaps by using a common prefix for classes specific to the module, like blog-header or storefront-title. There is a concept called "Object-oriented CSS" that might reduce the need for lots of redundant CSS and module-specific class names, but this is normally done during the design phase, not something you can "tack on" to an existing project.
Less HTTP requests is better, but you have to take file size into consideration as well as user behavior and activity. The initial download time of the entry page is the most important thing, so you don't want to bog it down with stuff you won't use until later. If you really want to crunch the numbers, try a few different things and profile your site with Firebug or Chrome's developer tools.
i think you can make global.css that store style that need every template.
And you could make css in each template.
Or simply use css framework like lescss

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.

How do I protect against XSS in CSS?

I'm looking at allowing users of our online system to control their own .css files with us by simply including them on a user by user basis.
What is the best way to avoid any potential XSS attacks in said files?
Is it possible to completely protect ourselves at all?
It would be possible for us to host the files for them and obviously then check them ourselves but it would be more convenient for our users to be able to update them as well.
The problem with allowing CSS is that many clever attacks can occur. CSS can be very dangerous indeed.
Some CSS expressions allow executing arbitrary JavaScript. This is difficult to prevent by blacklisting, so I'd suggest whitelisting.
Additionally, someone may create a CSS file that changes the page to impersonate another site, another page, or maybe it cleverly orients other elements on the page. Imagine if someone were able to position their own login form above your real one. Then they could intercept login requests. Depending on how your site is set up, this may or may not be possible; but be forewarned! Some know this as clickjacking.
Firstly, exercise caution, as others have said. Beyond that though, try and white-list the valid inputs you'd expect in the file. See if you can locate any libraries for your chosen framework (you haven't mentioned what this is), that can validate a string for CSS structure compliance.
The other thing you might to consider is parameterising certain CSS attributes and allowing users to configure them (i.e. color, font etc). This would significantly mitigate your risk as it takes out the ability to arbitrarily create your own malicious CSS (and conversely, create your own innocent CSS!)
As for your original question "Is it possible to completely protect ourselves at all?", that's easy - no!

Resources