W3C home > Mailing lists > Public > public-web-security@w3.org > December 2009

Re: Risks from CSS injection

From: Aryeh Gregor <Simetrical+w3c@gmail.com>
Date: Wed, 9 Dec 2009 11:24:04 -0500
Message-ID: <7c2a12e20912090824h3552acdbs91049af4081818fa@mail.gmail.com>
To: public-web-security@w3.org
My thoughts on this:

First, spoofing is not reliably preventable without server-side
whitelisting.  The entire *point* of CSS is to let authors make
something look totally different, so anyone who can inject CSS can
trick the user into clicking on the wrong thing.  On the other hand,
there are at least two important mitigations here:

* You can't easily use spoofing to make the user do anything they
couldn't otherwise do by clicking on something.  Spoofing is hard or
impossible to escalate to script execution, cookie disclosure, etc.,
without some further exploit.  Depending on what kinds of other
content you can inject into the page, you probably can't trigger more
than visiting a URL or maybe submitting a form -- either of which you
can probably persuade a lot of users to do anyway, just by saying
"Click here to see dancing pigs".
* Spoofing is almost always readily detectable.  For instance, if an
invisible link is made to cover the whole page, savvy users will be
tipped off that something is wrong by the fact that their cursor has
turned into a hand, and a URL is present in the status bar.  Or that
they click somewhere and go to a different page than they were
expecting.  Even if most users don't notice this, it only takes one
report to the site admin to get the exploit shut down, so the number
of people you can exploit is automatically limited.

As such, it would be reasonable for a lot of sites to allow CSS
injection without whitelisting despite the possibility of spoofing, so
it's not legitimate to dismiss more serious threats on that basis.  A
site that's okay with the possibility of spoofing might not be okay
with invisible information disclosure as is being discussed here.

As for invisible information disclosure, I think that's a much more
serious threat, mainly because it's typically hard to detect and very
reliable.  On the other hand, it's also something that CSS is in a
good position to clamp down on, because CSS is not intended to
disclose information to anyone.  So this is a good thing to think
about and try to mitigate.

Now, the only vulnerabilities I've ever seen that disclose information
to an attacker via CSS injection alone rely on inclusion of remote
resources controlled by an attacker.  As I said, this is a serious
problem, but I don't think CSS3 selectors are the problem here.  The
problem is allowing the remote resource to begin with.  As soon as an
attacker can include a resource that they control, they already have a
full list of IP addresses, referers, dates, and User-Agents, which is
a pretty massive information disclosure by itself.  Getting your first
name (unreliably, with a lot of effort) isn't a large additional
threat IMO.  Any site worried about information disclosure must block
all inclusion of remote resources in CSS.

So I think it would be worth it to think about ensuring that CSS
inclusion should never disclose information to remote sites as long as
a) url() is blacklisted, b) expression() is blacklisted, c) only
inline style is allowed, or some dummy rule is added at the top of the
stylesheet to prevent @import and @charset "UTF-7" and so on.  Once an
exploit requires a remote url() to be included in injected CSS, I
don't think we need to be worried about further information disclosure
unless it's very severe, e.g., password/cookie/POST variables.

In particular, I would suggest that nothing ever be added to CSS that
triggers access to remote resources but doesn't use url(), and is
allowed in inline styles or doesn't have to be at the top of the
stylesheet.  As far as I know, there are currently no such constructs
that exist or are planned, so blacklisting the (a)-(c) that I gave
should be safe.  Is this correct?  If so, does it sound like it's
feasible to keep it safe?

For anyone interested, what I suggested is more or less what MediaWiki
(ergo Wikipedia) does right now.  It allows anyone to add arbitrary
inline CSS, with url() and expression() blacklisted:


We've had some spoofing problems in the past
(<https://bugzilla.wikimedia.org/show_bug.cgi?id=9526>), but nothing
very serious.  (Nobody ever bothered fixing that bug, in fact.)  On
the other hand, we're very concerned about any kind of information
disclosure, including the IP addresses of our visitors, and I'm pretty
sure most other large sites are too.  Allowing third parties to access
your visitors' IP addresses is potentially against the law and/or your
organization's privacy policy.

(If there's some horrible vulnerability in our code that no one's
noticed until now, by the way, I'd appreciate hearing about it
off-list first.  :) )
Received on Wednesday, 9 December 2009 16:24:44 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Sunday, 19 December 2010 00:16:01 GMT