Re: [sysapps/runtime] cross origin XHR in packaged apps

On 01/04/2013 15:26 , Jonas Sicking wrote:
> First off I think we should enable some way for packaged apps to be
> same-origin with their "home site". I.e. if a developer running a
> website on http://www.example.com it should be possible for this
> developer to somehow distribute a packaged app that is same-origin
> with http://www.example.com.

That would indeed be great.

> There's some discussion around the challanges with this in [1].
 > [1] https://bugzilla.mozilla.org/show_bug.cgi?id=852720

Yes, it's a tricky problem. We've been through those discussions before, 
we even got a Recommendation out of it: WARP 
(http://www.w3.org/TR/widgets-access/).

Not that I'd necessarily recommend we use it.

Reading through that bug, there are several motley things that come to 
mind, so here are my notes in no particular order.

First, I have to say that I'm always concerned when I read about 
differences in behaviour between packaged and hosted apps when such 
differences go beyond things that fall more or less directly out of 
packaging. When we key behaviour off packaging, we introduce a fork in 
implementation. This means that the same code will behave differently 
depending on the delivery mechanism. We all know that Web technology is 
an intricate mess of tangled pieces, and experience shows that this kind 
of forking tends to have subtle (and not-so-subtle) ripple effects.

It also increases complexity and the attack surface.

I think that we should strive as much as possible for packaging to be 
orthogonal to the application concept. It should be possible to use 
packaging for an arbitrary web site (perhaps as an optimisation), 
including just for dependencies in the same way that it should be 
possible to install a hosted app. The only impact that packaging should 
have is on retrieval and (possibly) on signing. IMHO any other behaviour 
difference between hosted and packaging will lead to madness.

Just a side note: were I to defined the way in which packaging works, I 
would do so relying on the primitives exposed by Navigation Controller.

When it comes to assigning an arbitrary origin to an installed app, it's 
a worthy goal. The complicating factors are primarily that it risks 
opening up XSS attacks for sites that enable content upload, and that it 
should be possible to enable that behaviour for content not distributed 
through the origin (i.e. the famously popular 
http://marketplace.berjon.com/ installing an app that has as its origin 
http://sicking.cc/).

Having mulled this over, I have yet to think of a secure way in which 
this could happen without involving cooperation from the origin server. 
I don't really see how a CORS-like header would be useful on its own — I 
may be okay with *my* app accessing my site, but not others; and if I 
want CORS I can use CORS. Anything involving signatures through third 
parties tends to inherently suck.

What you really want out of this process is for the origin server to 
tell the runtime "yeah it's okay for this app to use my origin". You 
also probably want it to say "and have it run as if it were at this URL" 
in order to avoid URL space conflicts.

At the same time, this need to be really easy to deploy on the server. 
It should be possible to drop in some PHP/Node module/whatever, give it 
a pointer to the app, and all should be rosy. You could have something 
like this in the manifest:

     "originCheck": "http://sicking.cc/check-app/"

The runtime would then hit that URL in order to figure out if the app is 
allowed to use that origin. The exact details of the protocol depend on 
what we want to defend against. The endpoint can't just return 200 or 
echo something it's given because otherwise it's too easy to just hijack 
an existing service. It should at the very least perform some 
computation on the input. For instance, it could get a hash of the 
manifest and a nonce from the runtime, and return something based on those.

If we further want to defend against people deploying "yes scripts" that 
just accept any app under their origin (out of laziness) we could have 
the runtime send the endpoint the app's ID and the latter return a 
checksum of the manifest. Harder to deploy, but safer.

Further afield, I wonder if it would be interesting (for origin 
acquisition and other aspects) to build an AppID on concepts similar to 
BrowserID (notably making it federated) to enable apps to prove who they 
are without requiring everyone to have their own checking code or having 
too much riding on the backs of marketplaces. But at this point I'll 
admit I'm just waving my hands (winter just won't end here, it helps me 
stay warm). It might be wishful thinking since, sadly enough, we don't 
have a spec for BrowserID anyway.

Depending on the level of security built above, such origin hijacking is 
something that might work only in the installed case (as one of the 
automatically-granted privileges). But ideally I think it should be 
secure enough not to require that.

I also see that there are issues with OAuth redirection being raised. I 
wonder if those wouldn't best be handled as a separate issue. Notably, 
intents can intercept some specific URLs to pass to an application and I 
wonder if that wouldn't enable OAuth plugging for apps.

> However I also like the idea of enabling a privileged app to do
> network connections to a white-list of website. So basically a variant
> of the Firefox OS systemXHR and tcpsocket that only allows requests to
> a particular set of websites. This would be strictly more secure than
> what Firefox OS does now.
>
> This could be accomplished by adding additional information to those
> permissions in the manifest. So something like:
>
> permissions: {
>    systemXHR: {
>      description: "...",
>      servers: ["https://www.foo.com", "https://www.bar.com"]
>    }
> }

Ah, so that's basically reinventing WARP :) One thing I've come to 
wonder about over time is whether that level of granularity is truly 
useful. Whitelisting certainly mitigates against intranet attacks, but 
it's not so complex to poke holes in there: all you need to have is an 
application that can justifiably request access to everything (e.g., an 
RSS reader), which doesn't require all that much imagination. So I tend 
to think that if there's going to be a privilege to poke holes in the 
SOP, then it might just as well be boolean.

-- 
Robin Berjon - http://berjon.com/ - @robinberjon

Received on Tuesday, 2 April 2013 10:46:39 UTC