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 11 users

Issue metadata

Status: Archived
Owner:
Closed: Jun 12
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 2
Type: Bug



Sign in to add a comment

Security: Service Workers make JSONP XSS more dangerous

Project Member Reported by joh...@chromium.org, Oct 13 2014

Issue description

VULNERABILITY DETAILS
Suppose an attacker finds an XSS vulnerability somewhere on a domain, and also finds an XSS vulnerability in a JSONP callback on the same domain.

Since the JSONP callback will have a JavaScript Content-Type, it can be used as a Service Worker script, and hence an attacker can turn their XSS exploits into a persistent MITM of the entire origin, that will live on even if the first XSS is patched (as long as the JSONP XSS remains unpatched, since IIRC Service Workers get forcibly refreshed every so often?).

Unlike a normal XSS, which only works on specific pages where the attacker was able to inject content, a rogue Service Worker would be able to replace all content on all same-origin pages.

And unfortunately, JSONP XSS vulnerabilities are quite common, since JSONP handlers typically have a URL parameter letting you specify the function name to call, and -- thus far -- such an XSS has been able to cause only limited damage (IE6-8 apparently unsafely sniff content types, so can be tricked into loading it as HTML; in other browsers it can be used to get around some CSP restrictions[1]).

VERSION
Chrome Version: 40 (tentative, see  issue 364627 )
Operating System: all

[1]: http://homakov.blogspot.co.uk/2013/02/are-you-sure-you-use-jsonp-properly.html
 

Comment 1 by palmer@chromium.org, Oct 13 2014

Cc: slightlyoff@chromium.org jsb...@chromium.org
I thought this was being handled by the maximum lifetime feature of SW scripts? http://www.w3.org/TR/service-workers/#update-algorithm I could be misreading it, but I thought that was intended to mitigate the problem of persistent pwnage.
Labels: -Pri-1 -M-40 Pri-2
Status: WontFix
In M40, it looks like we'll be adding an OPT-IN CSP header and indeed we have the 24 hours update + update on every navigation.

IINM, in M40, the user will still have to close all affected tabs (or be told to by the affected website) for the new SW to take over the corrupted SW.

In M41, we plan to implement replace and reloadAll so that the new SW can take over the corrupted SW on its own without user intervention.

Based on that, I believe that this issue should be closed.
Chris, Joel: feel free to re-open if you have any concerns.

Comment 3 by jww@chromium.org, Oct 16 2014

A header opt-in definitely resolves my concerns. Thanks for getting on this so quickly.

Comment 4 by joh...@chromium.org, Dec 12 2014

Status: Available
I guess we should reopen this issue, since the opt-in header was removed in favor of path-based restrictions. See https://infrequently.org/2014/12/psa-service-workers-are-coming/ for an up to date list of Service Worker security mitigations.

Comment 5 by jww@chromium.org, Dec 12 2014

Hi John. Why doesn't the maximum lifetime of SWs address this problem? The attack doesn't seem any different really from having an XSS in the SW itself, which is one of the reasons the maximum lifetime exists.
2 things:

 - First, 24 hrs is not a maximum age of the SW, it's the maximum amount of time we allow a SW to live without checking for a new one (if you're using the site). If you're offline, the SW being b0rked is as much an issue as it would have been if the results of a pwn'd response had been far-futures cached.
 - That said, the max-lifetime-to-check IS a solution to this issue. Yes, the window of vulnerability is now larger (assuming your JSONP endpoint lives at or below the same path level as your documents on the same secure origin) than it would be in theory otherwise, but cleanup is pretty easy.

Sites that don't want SWs, or are worried about the amplifications that they might cause to other attacks, have simple solutions which we've baked into the system. I will write a blog post about incident response as jww@ suggested in another thread.
One last thing: a JSONP response is going to almost-always have a near-zero (or zero) max-age. That means we'll ALWAYS be checking with the server for an updated SW when you navigate to a pwn'd origin, reducing the timeframe for amplification significantly in the common case.

Comment 8 by falken@chromium.org, Jan 19 2015

Seems like WontFix based on comments #5-7?

Comment 9 by joh...@chromium.org, Jan 19 2015

Checking for updated SWs only helps if the server realizes its being attacked and patches the JSONP endpoint (though it's nice that they can fix such attacks quickly, assuming there isn't a network attacker blocking updates).

So no, comments #5-#7 don't prevent this.
slightlyoff: Can we get that blog post as promised in #6? I want to either mitigate this or have a clear statement that we must Accept This Risk.
Labels: M-44
Pulling into M44, let's resolve this finally.
Labels: Needs-Spec
This needs a decision on spec-side. Alex, could you address #10... do we mitigate or clearly state we assume the risk?
Labels: -Needs-Spec
Status: WontFix
Here is the link to Alex's blog post on the matter:
 https://infrequently.org/2014/12/psa-service-workers-are-coming/

Let me close.
Owner: slightlyoff@chromium.org
Status: Assigned
To be clear, the decision is to assume the risk. Alex will update the blog post as mentioned in comment #6 and #10.
Note also that the 24 hour update check can be bypassed using techniques like cookie bombing[1] unless servers protect against that.

[1]: http://mixedbit.org/blog/2013/04/11/dos_attack_on_cdn_users.html
Labels: -M-44 MovedFrom-44 M-45
[AUTO] Moving all non essential bugs to the next Milestone.  (This decision is based on the labels attached to your ticket.)


Ref: https://sites.google.com/a/chromium.org/dev/developers/ticket-milestone-punting-1
Could we apply some reflection detection in this case? We could fail with a security error if portions of the URL are appearing in code. Don't we do this already for pages?
+tsepez for thoughts on applying the XSS Auditor to JSONP
Cc: tsepez@chromium.org
actually +tsepez

Comment 20 by jww@chromium.org, Aug 13 2015

jakearchibald: In short, "no", although I'm CC'ing Master of XSS Filter tsepez in case he has a different opinion. Basically the XSS Filter only works on initial page parsing and never DOM injection for performance reasons, and this particular attack vector does not rely on page load.

Furthermore, the XSS filter has many, many known bypasses, and thus is not a real protection mechanism, but more of a "stop the stupid stuff" kind of filter.
XSSAuditor is part of the HTML parser, and such is not applicable to JSON.
But could we do something similar (after testing compatibility)?

Strawman: if the URL of a script subresource contains a string longer than 20 characters and containing characters other than [\w.] that gets reflected within the script (or perhaps only near the beginning), then stop executing that script.

Comment 23 by homakov@gmail.com, Aug 15 2015

Why don't just require explicit header Content-Type:text/javascript-service worker instead? Service worker script and JSONP/JS are two different things, thus should be treated differently and have different content type.
Cc: jeremyarcher@google.com
As an experiment, I've implemented johnme@'s suggestion as:

  https://codereview.chromium.org/1308703002

Specifically, this code blocks segments (separated by = and &) in the query string
that appear anywhere in the service worker script (as long as they are >= 20 bytes).
Making this change causes two layout tests to fail:

  http/tests/fetch/serviceworker/filtered-response-base-https-other-https.html
  http/tests/fetch/serviceworker/thorough/access-control-base-https-other-https.html

Thoughts?
Labels: -M-45
XSS filter usually needs to rely on several heuristics and there could be always ways to bypass such filtering, while it might be still helpful to 'stop the stupid stuff'.

tsepez@, jww@: What security folks think about an approach like #22 / #24? Would it be worth pursuing?

Comment 26 by jww@chromium.org, Aug 21 2015

tsepez@ will need to give a more definitive answer, since he's the expert here, but this approach generally sounds and looks fine to me, as long as the performance cost isn't too great.
I expect the false positive rate will be high.  Maybe you want to measure this with an UMA stat first.  What happens if we do a query like:
  ?user=o'malley
and get back:
  callback({"user": "o'malley", "id":41192});

In other words, I'd expect many query terms to get reflected as part of the returned JSON.
(Cross-post) I've created a spec discussion item to consider compatibility concerns:

https://github.com/slightlyoff/ServiceWorker/issues/743
What do we expect from the spec discussion for auditor one, other than something like #23?  It's not too obvious to me.

From implementation pov I feel we could do a bit more investigation on what the existing XSSAuditor is doing and what we could/want to share with it, as well as adding UMAs to collect more data to support the current idea and hypothesis.
#29 I think we can do spec discussion and impl work in parallel, this bug thread includes proposed heuristics and solutions which I feel is better done in specland so other browser vendors and interested parties can comment (I actually long ago considered moving this bug to a spec one, that's what I was going for in comment 12). We can certainly do more impl work to get more informed input for the spec discussion.
I see, so it's more about discussing what spec could do to protect possible XSS attacks on ServiceWorker?  The issue OP looked focusing on the auditing heuristics, which confused me a bit.
Maybe some context got lost. Jeremy and I were thinking it's not likely that a web dev would use a service worker script URL in the way illustrated in comment #27, so it wouldn't be a case to worry about. And even if UMA today shows no SW in the wild now does, if we do that route, I wanted to make sure there's a public spec decision that it's not a supported case.
Labels: Hotlist-Recharge
This issue likely requires triage.  The current issue owner may be inactive (i.e. hasn't fixed an issue in the last 30 days or commented in this particular issue in the last 90 days).  Thanks for helping out!

-Anthony
Owner: falken@chromium.org
Status: Archived (was: Assigned)
We've been shipping service workers for several years with the current state of things. I don't think we are going to change anything here unless there is additional information than already stated in this bug to change our minds.

Sign in to add a comment