Apps/PackagingProposal: Difference between revisions

trusted -> privileged
(trusted -> privileged)
 
(6 intermediate revisions by one other user not shown)
Line 1: Line 1:
= Trusted Apps =
= Privileged Apps =
 
We have the following assumptions about Privileged Apps, as stated at [[Apps/Security]]:
* 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 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 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.
* 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 privileged app should use a different "cookie jar" than resources from the developer's website. This so that the privileged 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 privileged app by hacking the developer's website and overwriting data which the privileged 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.
* The resources in a privileged app should not be "same origin" with any resources other than ones from the same privileged app. I.e. if a privileged 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 privileged app. This is since otherwise it would obviously be significantly easier to hack a privileged app by hacking any websites that it opens in <iframe>s.


= Delivering Trusted Apps =
= Delivering Privileged Apps =


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.
Our initial thoughts for how to implement these requirements were that privileged 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.
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.
However, there are a couple of problems with this solution.
== Serving Privileged Apps from the Web Won't Work ==


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
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
Line 24: Line 28:


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


= Packaging for Trusted and Certified apps =
= Packaging for Privileged and Certified apps =


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.
Hence we have changed the plan to instead base privileged apps on a "packaged" solution. The idea will be that to publish a privileged 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 <tt>https://developer.com/myapp.html</tt>, and a page which was part of the developer's website would have the URL <tt>https://developer.com/index.html</tt>. 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.
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 privileged app a page that was part of the app would have URL <tt>https://developer.com/myapp.html</tt>, and a page which was part of the developer's website would have the URL <tt>https://developer.com/index.html</tt>. 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, <tt>app://</tt>, 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 <tt>app:// developer.com/myapp.html</tt>. 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.
Instead I think that we introduce a new protocol, <tt>app://</tt>, which is used to load all resources in privileged 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 <tt>app:// developer.com/myapp.html</tt>. 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 <tt>app://developer.com/</tt> to make network requests to <tt>http://developer.com</tt>. I.e. the app would be allowed to open <tt>XMLHttpRequest</tt> connections to <tt>http://developer.com/myapi.cgi</tt> without requesting any special privileges. Likewise images and videos loaded from <tt>http://developer.com</tt> would not be considered cross-origin for example for the purposes of tainting when drawn into a <tt><canvas></tt>. 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.
To make things more similar to how web pages normally work, we could allow pages from <tt>app://developer.com/</tt> to make network requests to <tt>http://developer.com</tt>. I.e. the app would be allowed to open <tt>XMLHttpRequest</tt> connections to <tt>http://developer.com/myapi.cgi</tt> without requesting any special privileges. Likewise images and videos loaded from <tt>http://developer.com</tt> would not be considered cross-origin for example for the purposes of tainting when drawn into a <tt><canvas></tt>. 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.
Line 48: Line 51:
= Webby-ness =
= Webby-ness =


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.
All in all this definitely means that privileged 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, privileged 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.
In the long run I definitely want to make privileged apps more "webby". Both by changing our privileged 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.
Confirmed users
717

edits