Can we please declare that follow-ups should go to the dev-webapps list only?
See Mounir's plea from some months ago that we not share threads between mailing lists. (The short version is: A discussion on two lists sucks for everyone except those subscribed via e-mail to both lists.) On Mon, Jul 9, 2012 at 1:04 PM, Jonas Sicking <[email protected]> wrote: > Hi All, > > This email has unfortunately taken longer to send then I wish, mostly > because I've been on vacation and travelling for the past three weeks, > hence feedback on this is more urgent than usual. > > We've had numerous threads on this list about trusted apps being different > from "plain" apps in a few ways. As we've been diving into the details > about how to implement trusted apps, we have realized some big problems > with the design we had in mind. Hence I'm proposing a new solution for how > trusted apps will work. > > Please note that the various requirements and solutions in this email > *only* applies to trusted and certified apps. It does *not* apply to > "normal" apps, i.e. apps which don't use of any of the APIs which are only > available higher privilege apps. You will be able to do anything that you > can do in a web page today, and more, without worrying about any of the > restrictions in this email. > > With that, let me start by enumerating the requirements that we have had in > mind for trusted apps: > > * They are reviewed in some form. I.e. a trusted party has indicated some > level of trust in the application. In the initial version of B2G we've had > as a requirement that the store should review the actual app contents. In > future releases I'd also like to support stores indicating trust in the app > developer rather than the app itself, but this isn't slated for the initial > B2G release. > * They are signed. This is needed in order to verify that the app actually > contains the reviewed content. It also protects against someone hacking the > webserver which the app is served from. > * They use a minimum CSP policy in all pages in the app. This to ensure > that the app doesn't get hacked using XSS attacks. I.e. we want to ensure > that only the app developer's code runs, and not an attacker's code. > Obviously this will never be perfect, but it will hopefully help a lot. > * The resources in a trusted app should use a different "cookie jar" than > resources from the developer's website. This so that the trusted app can > rely that the data it stores in cookies, indexedDB, etc isn't compromised. > I.e. this is to further make it possible to hack a trusted app by hacking > the developer's website and overwriting data which the trusted app relies > on to make it behave in ways it otherwise wouldn't. > * The resources in a trusted app should not be "same origin" with any > resources other than ones from the same trusted app. I.e. if a trusted app > creates an <iframe> pointing to the developer's website, javascript running > inside the iframe shouldn't be able to reach out and touch the objects in > the trusted app. This is since otherwise it would obviously be > significantly easier to hack a trusted app by hacking any websites that it > opens in <iframe>s. > > Our initial thoughts for how to implement these requirements were that > trusted apps should use largely the same delivery mechanism as normal apps. > I.e. they should live as normal files on the developer's web server. The > resources would then be cached using the normal app cache. The signatures > for the reviewed files would be gotten from the store at the time of > installation as well as any time the app is updated. > > We came up with this solution since we wanted to avoid "packaging" apps > into some sort of archive (like zip) and delivering it through the store. > W3C widget specs and Chrome apps use this solution. > > However, there are a couple of problems with this solution. > > As Brian Smith has pointed out, signing HTTP responses isn't trivial. > There's a significant risk that proxies will change headers on the way > between the server and the user's browser. There even some risk that > proxies will change the contents of the response bodies themselves. During > normal browsing this isn't a big deal. But when the responses are signed it > means that the response is completely rejected, leading to a very bad user > experience. The only way to really prevent this is to always use https to > serve the resources. However, this can be a non-trivial cost for the app > developer. > > Once we have several stores, stores will inevitably take a differently long > time to review an update of an app. This will cause confusion since the > different stores will be serving different signatures for the resources of > the app. One solution would be for the app developer to always use new URLs > for every version of the app. However, this is problematic if you are > developing a twitter app and want to enable sending emails containing links > to individual tweets since those links would then point to a specific > version of the app. Another solution would be for stores to not serve the > new signatures until the developer says that the new version is published, > and then for the developer to publish the new version only once all stores > have reviewed the new version. But this limits publishing speed to the > slowest store, which is likely not acceptable, and also means that no store > has an incentive to review quickly. > > Additionally, there are some things that are very non-webby with this > solution. > > Signing the resources means that you can no longer generate your HTML or > image files on the fly using php, perl, ruby, etc. This is because you > would have to generate a new signature at the same time as you generate the > file contents. However generating a new signature would require having the > private key on your web server, which largely defeats the purpose of > signing since if someone hacks the web server, they can create their own > signed resources. Hence signing effectively requires that the resources are > static files located on the server. > > Also, since it's the store that has to review the app and send new > signatures for any updated version, it means that publishing a new version > of your app no longer means simply updating the contents of your web > server. You also have to contact the stores which you are selling your apps > through and ask them to re-review your app and create new signatures for > the app's resources. > > > When looking at the proposed solution this way it seems like we have come > up with something that is the worst of both worlds. App developers are > forced to create apps which consist of static resources and every time they > want to publish a new version they have to contact all stores that they > want to sell their app through. This feels a lot like a packaged app, the > only difference is that the resources live as separate files on the > developers server rather than as a zip file in the store. Yet app > developers have to serve their apps through SSL and deal with coordinating > publishing through multiple stores. This is non-webby, a pain to publish > through and potentially expensive. > > Hence we have changed the plan to instead base trusted apps on a "packaged" > solution. The idea will be that to publish a trusted app the developer will > create a zip archive which contains the app manifest as well as all > resources needed for the app. The app can then be sent to all stores which > the developer wants to publish the app trough. These stores can then review > the app and sign the package. At installation time the signed package is > downloaded by the B2G from the store and the package is verified against > the signature. > > > One obvious question once you go with a packaged solution is what URLs the > packaged resources will be available through. My initial thought was to > keep things as webby as possible and to make the resources in the package > available as normal http or https URLs. The goal was that packaged apps > would behave as much as possible as non-packaged apps. This would mean that > in a trusted app a page that was part of the app would have URL > https://developer.com/myapp.html, and a page which was part of the > developer's website would have the URL https://developer.com/index.html. > Yet the two pages would use different cookies, and any same-origin checks > would have to say that the two pages are different. This is to satisfy the > last two requirements in the bullet list at the beginning of this email. > This is certainly implementable, however it seems very confusing for > developers. > > Instead I think that we introduce a new protocol, app://, which is used to > load all resources in trusted apps. This is an idea that Jim Straus came up > with over in bug 707625. Introducing this new protocol certainly has the > disadvantage that it feels less webby, however I think the benefit in > clearing up the confusion above outweighs it. It makes it very clear which > pages will receive which cookies, and which pages are same-origin and thus > can reach in to each other. To make things as webby as possible though, I > think such URLs should be given a "real" domain, like app:// > developer.com/myapp.html. This would be the domain of the developer, i.e. a > domain that the developer has to own. We would have to come up with some > mechanism for verifying this ownership though. > > To make things more similar to how web pages normally work, we could allow > pages from app://developer.com/ to make network requests to > http://developer.com. I.e. the app would be allowed to open XMLHttpRequest > connections to http://developer.com/ <http://developer.com/.>myapi.cgi without > requesting any special privileges. Likewise <img>s and <video>s loaded from > http://developer.com would not be considered cross-origin for example for > the purposes of tainting when drawn into a <canvas>. This way most of the > code which would work for a website would work in a packaged app, except > that the packaged app would have to ensure to use absolute URLs when > wanting to connect to the website. > > In order to keep applications isolated from each other (except through > explicit APIs like WebActivities) the app:// protocol always maps to > loading from the package that the load is initiated from. Consider a user > which has a facebook app and a google maps app installed. Whenever the > facebook app loads an app:// URL, we always look in the package which > contains the facebook app. If the resource isn't found there we return a > 404 error. I.e. we never even look at the google maps package, even the > facebook app tries to load something like app://google.com/map.html, the > result is simply a 404. This also means that it's not a problem to install > two apps from google which both contains the same app:// > google.com/library.js URL. Each app would simply load the library.js file > from its own package. > > > There are still lots of parts that we need to figure out. First of all we > need to define an exact format for the package. There are lots of formats > out there for signed packages, .jar which is commonly used by java, .xpi > which Firefox uses for addons, .crx used by Chrome, etc. We can either pick > an existing one, or design a new one. I'll explicitly declare it off topic > for this thread to come up with the specific format. Please start separate > threads about that. > > We also need to come up with an update mechanism. One solution would be to > every now and then check the URL which we used to download the original > package to see if a new version is available. Another solution would be to > send a single request to the store enumerating all apps which we want to > check for updates for. That would allow for less traffic in the common case > of no apps needing any updates, but might be more complex to implement and > could have privacy implications. Again, this is off topic for this thread, > please start separate threads if you want to discuss this topic. > > > All in all this definitely means that trusted apps won't be as webby as > normal apps. However as long as we have the requirements around signing by > the store, an enforced CSP policy and a separate cookie jar, trusted apps > simply won't be very webby. Whether we zip the files up in an package and > deliver them the store for signing, or we deliver them through the store > through http, is a relatively small difference which only affects the > deployment of the app, not the development. > > In the long run I definitely want to make trusted apps more "webby". Both > by changing our trusted apps work, and also by giving the web more > capabilities so that they can meet somewhere in the middle. But I think the > above proposal is a good way to start by doing something secure which will > give us experience and help us develop something better in the future. > > / Jonas > _______________________________________________ > dev-b2g mailing list > [email protected] > https://lists.mozilla.org/listinfo/dev-b2g _______________________________________________ dev-webapps mailing list [email protected] https://lists.mozilla.org/listinfo/dev-webapps
