New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 4 users

Issue metadata

Status: Verified
Last visit > 30 days ago
Closed: Jan 2010
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 2
Type: Bug-Security

  • Only users with EditIssue permission may comment.

Sign in to add a comment

Issue 9877: Security: cross domain thefts via CSS string property injection

Reported by, Apr 8 2009

Issue description

This bug is kind of annoying. The hope is that something can be done at the
browser level. We really don't want to have to make sweeping changes to
lots of our applications, and generally burden web apps with more web
browser issues.

This affects Chrome, Safari, IE, Opera and FF. But let's keep this bug
Chrome-private whilst we debate what can be done (and protect our customers
first :)

The attack involves cross-domain CSS stylesheet loading. Because the CSS
parser is very lax, it will skip over any amount of preceding and following
junk, in its quest to find a valid selector. Here is an example of a valid

body { background-image: url(''); }

And here is an example of a valid selector embedded in an XML document
(this is a paraphrase of a real example low-severity attack):

<photo_comment from="evil"> blah { blah:0 } body { background-image:
url('</photo_comment><photo_comment from="trusted"
url="url_with_key_to_hidden_photo">some secret
comment</photo_comment><photo_comment from="evil"> ');}</photo_comment>

As you can see, if the attacker can inject a couple of strings into a
trusted response, there is a useful attack here. The data is stolen cross
domain with e.g. window.getComputedStyle(body_element,
(Note that the seemingly redundant blah { blah:0 } selector is to resync
the CSS parser to make sure the evil descriptor parses properly).

There are a surprising number of places in our products where an attacker
can do this. It can apply to HTML, XML, JSON, XHTML, etc.

The main common construct that prevents exploitation is newlines.
Obviously, newlines cannot be considered a defense! The exploitable places
in Google include some JSON and XML data APIs that return responses on a
single line. Some of our XHTML / HTML just happens to be emitted this way too.
Regarding JSON and XML, note that it is not currently a security
requirement to escape ' and " (XML values) or ' (JSON values within double
quoted strings). Nor should we make it a requirement.

Regarding how to fix the browser, here are some starting ideas (from an
ise-team brainstorm).

1) When loading cross-domain CSS, engage a stricter parsing mode that stops
on first syntactic (but not sematic of course) errors.

2) Same as 1), but also only engage when the MIME type is not CSS.

3) Some variant of 1) or 2) but only engage when X-Content-Type-Options:
nosniff is seen (won't help most of the internet).

4) When loading cross-domain CSS, do not send cookies (probably breaks the
internet :-/ )

Please, feel free to cc: additional people who may be able to help. But try
and keep within Google for now.

Comment 1 by, Apr 8 2009

Labels: -Pri-0 -Area-Misc Pri-2 Area-WebKit
We can probably fix this for sites that use X-Content-Type-Options: nosniff by requiring the correct MIME type 
when loading a style sheet.  That will fix 99% of the problem (at least for nosniff sites).

Comment 2 by, Apr 8 2009

Option 1) is probably not feasible in the sense that when you set Firefox error
console to log all messages, and browse the Web even for a short while, or even just
use Google services alone, you are going to accumulate an obscene number of CSS
syntax warnings. Part of the reason is precisely that CSS parsers resync after
errors, so it's easy to miss typos and move on. 

Plus, parser modes that depend on content origin would be pretty damn
counterintuitive and confusing (but then, so is the current resync behavior to begin

The nosniff variant seems to be the only one that could be plausibly sold to others
in the short run, although the downside is that it may work against us in some
contexts (for example, we started outputting nosniff by default in some contexts, and
if this change would break apps that currently work fine, bah).


Comment 3 by, Apr 8 2009

I can't find it in the archives, but has reading of content from other websites not 
been around for ages? IIRC you used to be able to detect and read local files in MSIE 
if they even slightly resembled css using the cssText property.

Maybe we can put all the object associated with the cross domain stylesheet in the 
domain of that stylesheet, preventing JavaScript from reading/setting properties 
cross domain? You may still be able to leak information if it's present in some very 
specific form, eg: the cross domain target contains data that sets the dimensions of 
an object and you can determine the actual dimensions of the object, thus leaking 
part of the data.

IIRC Flash allows x-domain xmlhttp requests with access control through a file on the 
server. Maybe we won't save the current internet, but considering where the internet 
is going, maybe it is time to allow servers to fine-tune what can and cannot be 
loaded x-domain in some way. The server would by default get whatever behavior we 
have now, but by providing an access control list, it defaults to allowing nothing to 
be loaded from another domain. The access control list is a white list of what the 
server does allow other websites to be load x-domain and in what way. 
eg the access control list for "" could be:
  local-url: ""
  remote-url: "http://*"
  type: "javascript"

  local-url: ""
  remote-url: "https://*"
  type: "javascript"

This would disallow everthing but loading "" 
from any http page as a javascript (or "https://..." from any https page).

The format of the access control list may need a bit more work :)

Comment 4 by, Apr 8 2009

What about option 2) then? Combined with full knowledge (if not
support) for CSS3 _syntax_.

I'm suggesting that syntax errors (e.g. CSS starts with <xml>) should
abort parse. Semantic errors such as unknown property or unsupported
property value or unsupported piece of CSS3 syntax would not abort


Comment 5 by, Apr 8 2009

Hey Skylined,

Properties giving raw access to stylesheet text are restricted in FireFox, IE and
Opera. Not Chrome; I have a separate old bug open for that. I don't think this
capability adds too much to this attack.

Even with DOM access closed down, there's still the getComputedStyle() thingy. We
could restrict that but STILL there would be a leak. The background-image URL
property causes a fetch to where the path component /blah is the
sensitive info.

There may be other easy ways a web page can determine what the cross-domain valid CSS
content was.


Comment 6 by, Apr 8 2009

2) is probably also somewhat confusing and may break a bunch of sites (since
typically, there are no security consequences with serving static CSS as text/html or
text/plain)... although IIRC, WebKit is giving out warnings on bogus MIME types for
CSS already, so this much works in our favor.

Comment 7 by, Apr 8 2009

Yes, you are right: if we allow the x-domain loads but try to prevent information 
leakage, we would probably get daily reports of ways to tease information out of the 
css. That's not a game I like to play.

So, we either try to detect malicious abuse with acceptable false positive/negative 
rate, or allow websites to protect themselves. I'm all for trying the first in the 
short term, but designing the later for the long run.

Comment 8 by, Apr 8 2009

Status: Untriaged
@skylined: We should engage with Mozilla's effort in this direction:
security-policy/.  I'm not sure if they cover this use case, but it seems in scope for their effort.

Comment 9 by, Apr 8 2009

Labels: Mstone-2.1
Status: Available

Comment 10 by, Apr 8 2009

It looks like there may be no easy heuristic fix? :-/
I strongly dislike relying on X-Content-Type-Options, because that again puts burden
on application developers, which is not fair game IMHO.

Do we really think a ton of web sites do:
1) Cross-domain CSS loads.
2) Whereby the MIME type of said file is not CSS.
3) And furthermore, the CSS is malformed (as opposed to not supported) when parsed
with full CSS3 syntax?

Comment 11 by, Apr 8 2009

Individually, each of these is likely pretty common. A conjunction of all three might
or might not be rare. I think that Chrome team had some way to set up an experiment
with a watchpoint for certain conditions, and process aggregate data, but I might be
making stuff up.

Comment 12 by, Apr 9 2009

We have capability to perform experiments. Also ISE could look at our cache and 
guesstimate the level of breakage likely to occur.

Comment 13 by, Apr 9 2009

The nosniff thing is probably something we want to do anyway.

We can measure this kind of thing, but it's a bit hairy because the bits we need are buried deep in WebCore 
whereas UMA lives in chrome-land.

Is the only reason this doesn't work for JavaScript because the JS parser is much stricter than the CSS parser?  
What about other parsers, like the SWF parser?  There are lots of different formats you can load cross-origin and 
interact with.

Comment 14 by, Apr 9 2009

Javascript parser is more relaxed when it comes to syntax conventions, *but* fails
hard on first syntax problem, so it won't glance over bits of HTML, etc, desperately
looking to resume parsing later on. The risks of cross-domain script inclusion are
pretty well understood, and there are some good mitigations in place that are less
hacky than any CSS workaround would need to be. The only area where JS parser is
comparably dangerous to CSS is E4X, but thankfully, most browsers do not support it.

Flash (crossdomain.xml), Java (GIFAR), and related parsers had bugs that permitted
them to overzealously interpret content across domains addressed in them in the past.
HTML/XHTML/XML sniffing is another problem, but it's also being tightened up a bit by
all parties.

Comment 15 by, Apr 9 2009

> The nosniff thing is probably something we want to do anyway.


> We can measure this kind of thing, but it's a bit hairy because the bits we need 
> are buried deep in WebCore whereas UMA lives in chrome-land.

We now have support for UMA reporting from the renderer.  That part of hooking up the 
experiment should be easy now.

> The only area where JS parser is comparably dangerous to CSS is E4X, but 
> thankfully, most browsers do not support it.

Firefox does, so I guess they get to worry about this one too.

Comment 16 by, Apr 9 2009

I tested IE8, and their nosniff doesn't trigger strict MIME processing for style 
sheets.  I'm talking with ericlaw about whether this makes sense to add.  I think we 
should perform the following measurement experiments:

1) How often is a style sheet loaded with the wrong MIME type (maybe separate "no 
Content-Type" from "incorrect Content-Type").
2) Quantity (1) conditioned on the load being cross-origin.
3) Quantity (1) conditioned on the load having the nosniff directive.
4) Quantity (2) conditioned on the load having the nosniff directive.

That should give us some amount of useful information.

Comment 17 by, May 22 2009

Labels: -mstone-2.1 mstone-3

Comment 18 by, Jun 5 2009

Status: Assigned
Do we have a plan for fixing this?  It seems like we have stopped working on it.

Comment 19 by, Jun 5 2009

I don't think we have a plan for fixing this for Mstone-3.  Now that Chris is on the 
team, maybe we should assign this bug to him?  :)

Comment 20 by, Jun 5 2009

Labels: -mstone-3 Mstone-X
We actually don't have any specific time frame for this. We also don't have any 
concrete plan on the table.

Comment 21 by, Sep 6 2009

Labels: -private Restrict-View-SecurityTeam

Comment 22 by, Sep 26 2009

I don't think I ever filed an upstream WebKit bug about this.
I'll try and enthuse my WebKit security contacts to fix this. If they aren't 
enthused, I'll just blog about it to stimulate debate on how to fix without breaking 
the web.

I did try hacking up this strategy into my local build:
- For different-domain CSS loads, require a valid MIME type (existing "strict" logic, 
which I reused, needs text/css, <blank>, or some weird binary type).
- Apply to <link rel="stylesheet"> and @import
- Crash hard whenever a CSS load is denied due to bad MIME type.

It seemed to work OK, i.e. lots of cross-domain loads logged by no hard crashes.

Comment 23 by, Sep 29 2009

Status: Upstream
Upstream WebKit bug:

(Includes concrete test case against Yahoo! Mail and hacky demo WebKit patch which 
refuses to load cross-domain CSS if the MIME type is incorrect).

Comment 24 by, Oct 29 2009

Status: Started

Comment 25 by, Oct 30 2009

Comment 26 by, Nov 11 2009

Labels: -Mstone-X Mstone-4
Targeting for M4. I have a WebKit patch in review.

Comment 27 by, Nov 24 2009

Labels: ReleaseBlock-Stable
This won't make it in for Beta unless someone finishes and lands it for Chris. 

I'll tentatively target for Stable, though I haven't seen the patch so I don't know how 
crazy it would be to take it after Beta.

Comment 28 by, Nov 24 2009

There was some resistance upstream.  I suspect that without Chris here to drive the
patch, this will end up in Mstone-5.

Comment 29 by, Dec 7 2009

I'll get this into Mstone-4 one way or another :)

Comment 30 by, Jan 6 2010

Labels: SecSeverity-Medium
Status: FixUnreleased
Committed as of WebKit r52784.
Merged above change into Beta branch with Chromium r35592.

Eventual fix -- chosen to maximize compatibility -- is:
"Block stylesheet loads if it is a cross-origin load where the MIME type is incorrect 
and the resource does not start with a valid CSS construct".

Comment 31 by, Jan 12 2010

Verified with

Comment 32 by, Jan 20 2010

Labels: -Restrict-View-SecurityTeam
Status: Verified
(Already public; removing view restrictions)

Comment 33 by, Mar 21 2011

Labels: Type-Security

Comment 34 by, Oct 5 2011

Labels: SecImpacts-Stable
Batch update.

Comment 35 by, Oct 13 2012

Project Member
Labels: Restrict-AddIssueComment-Commit
This issue has been closed for some time. No one will pay attention to new comments.
If you are seeing this bug or have new data, please click New Issue to start a new bug.

Comment 36 by, Mar 10 2013

Project Member
Labels: -Area-WebKit -Mstone-4 -SecSeverity-Medium -Type-Security -SecImpacts-Stable Security-Impact-Stable Cr-Content M-4 Security-Severity-Medium Type-Bug-Security

Comment 37 by, Mar 13 2013

Project Member
Labels: -Restrict-AddIssueComment-Commit Restrict-AddIssueComment-EditIssue

Comment 38 by, Mar 21 2013

Project Member
Labels: -Security-Impact-Stable Security_Impact-Stable

Comment 39 by, Mar 21 2013

Project Member
Labels: -Security-Severity-Medium Security_Severity-Medium

Comment 40 by, Apr 6 2013

Project Member
Labels: -Cr-Content Cr-Blink

Comment 41 by, Oct 1 2016

Project Member
This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit - Your friendly Sheriffbot

Comment 42 by, Oct 1 2016

Project Member
Labels: Restrict-View-SecurityNotify

Comment 43 by, Oct 2 2016

Project Member
Labels: -Restrict-View-SecurityNotify
This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit - Your friendly Sheriffbot

Comment 44 by, Oct 2 2016

Labels: allpublic

Sign in to add a comment