FirefoxOS/New security model

From MozillaWiki
Jump to: navigation, search

Goals

  • Enable exposing "sensitive APIs" to 3rd party developers.
  • Use the same update and security model for gaia and for 3rd party content.
  • Don't require content which uses "senstivie APIs" to be installed. Users should be able to simply browse to it.
  • Don't have separate cookie jars for separate apps. At least for normal content which doesn't use "sensitive APIs".
  • Ensure that content which uses "sensitive APIs" always runs in a separate process. Enforce in the parent process that only these separate processes can trigger "sensitive APIs". I.e. hacking a child process should not permit access to more sensitive APIs.
  • Enable content which uses "sensitive APIs" to have normal http(s) URLs such that they can use OAuth providers like facebook.
  • Enable content which uses "sensitive APIs" to use service workers.

"Sensitive APIs" here means APIs that we have not figured out how to safely expose to normal web pages. About 5-10% of the content in our marketplace falls into this category, and none of the content on the rest of the web fall into this category. I.e. most content does not use sensitive APIs, and can and should remain as normal websites.


New Security Model

Signing - bug 1153420

We will require that all content which uses "sensitive APIs" is signed. For now only the firefox marketplace will be allowed to do the signing. Possibly this will be changed in the future, but that's likely more a policy change than a code change.

Signing is done by having the developer package the content into a package and submit it to the mozilla marketplace. The marketplace will review the app and then add a signature to the package. The developer can then download the signed package and upload to the developer's website.

Issue: Should we allow other forms manual review of each app? Can the marketplace "review a developer" and give the developer access to automatic signing?

The format used for the packaging will be the one defined in the W3C packaging spec draft. A header is added to the package to indicate that it's a signed package. The advantage of this packaging format, compared to zip, is that it's streamable.

The format used for the signature is still to be determined, but hopefully we can use the same file formats and file names as used today. However it's important that the signatures also cover the header data for each resource, as well as the header data for the package itself.

Issue: Decide on exact signature format. Should we require that the signature-files live at the start of the package. That way we'd always have the signature available before the file contents covered by the signature.

Verifying signatures - bug 1153422

To load a webpage in a signed package, the user navigates to a URL like "https://website.com/RSSReader2000/package.pak!//index.html". The part before the "!//" is the URL to the package itself. The part after the "!//" is the resource path inside the package.

So loading signed content does not require an installation to happen. Simply navigating to a URL like the above is enough.

When the user navigates to such a page, Gecko will download the package from the webserver. Gecko will then see in the header of the package that the package is signed.

Before serving any resources from the package to the rest of Gecko, the network layer will first wait for the signatures to be loaded from the package. It will also verify that the resource that is currently being loaded is covered by, and matches, the signature.

We should likely cache which resources in the package that we've checked the signature of, so that we don't have to recheck if a resource is loaded multiple times.

Another thing that needs to be done before any content is served by the network layer is to look in the manifest and populate the nsIPermissionManager database with any permissions enumerated in the manifest. After having checked that the manifest properly matches the signature of course.

CSP - bug 1153423

We need to make sure that it can't load scripts from outside of the signed package. And we need to make sure that it can't use inline scripts.

The plan is to use the CSP code to accomplish this. We can mainly leverage existing code which enables applying a default CSP policy to certain content. We'll use this to apply a default CSP to all signed content similarly to how we currently apply a default CSP to all privileged apps.

We'll also need to extend it to enable it to enforce loads to happen "from same package", rather than just "from same origin".


We also can't allow signed content to be opened in an <iframe>, other than by pages from the same signed package. This is partially to prevent signed content from getting clickjacked. However it's also because we want to always open signed content in a separate OS process, and currently gecko does not support out-of-process plain <iframe>s.

Hopefully this is a restriction we can eventually relax, for example by allowing pages in a signed package to opt in to being iframe-able. But this will require out-of-process <iframe>s and so will have to wait.

Process isolation - bug 1153428

In order to ensure that only signed content can access the APIs that it has been signed for, we want to always use separate child processes to run such content.

This means that when a user navigates from an unsigned page to a signed page, that we need to switch which process render the pages. Right now this can only be done by creating a new <iframe mozbrowser>.

However only Gecko knows that a particular URL is signed. Gaia could not simply look at a URL to know if it will return signed content or not. And Gecko only knows that it's signed content once response data starts arriving.

Even if we add some way for gecko to signal to the <iframe mozbrowser> embedder that a new <iframe mozbrowser> needs to be created, this will make going "back"/"forward" between the two very messy.

We also need to change security checks that currently are done in the parent process. Currently many of them are heavily based on app-ids and installed apps. This may need to be changed.

Installing and updating - bug 1153432

Issue: How can we register web activities when we pin a page. And update those registries when the pinned manifest is updated.


Signed packages follow normal http semantics. I.e. if the package still exists in our http cache when the user revisits a signed page, but the cache headers indicate that the content needs to be updated, we do a normal GET request to see if a new version needs to be downloaded.

If a new version of the package is being sent, we follow the same behavior as when visiting a package for the first time. I.e. we need to reverify signatures as well as update any permissions in the nsIPermissionManager database.

However, we want to avoid having to download a whole package if just part of it has changed. In order to support that we hope to enable the server to respond to the GET request for an updated package with just a "diff" of what's changed between the previous and current version.

One possible way to do this would be to have gecko indicate that it supports a new type of content encoding as well as send the etag of the current package file. The server can then look at the etag and if it has (or can generate) a diff between the clients version and the latest version, it can respond with a special content-encoding as well as the package diff.

Gecko can then use the diff to patch the existing package.

Note that sending a diff is entirely the server's choice. If the server doesn't support this newly created diff mechanism, then it will simply serve a full package. Likewise if the user is on a very old version which the server doesn't have a diff for or if the diff has bigger size than the resulting package, the server can simply serve a full package.

In the case when a diff is received, it is probably fine to not support streaming package content. I.e. in that case its probably fine to wait for the full diff to be downloaded and applied, before returning any data from the Gecko network layer.

We do in that case still need to verify signatures of the new package version.

Installing a signed package mainly consists of pinning it in the http cache such that it doesn't get evicted. We still need to check for updates according to normal "app update" scheduling.

Service Workers - bug 1153433

One of the central pieces of the new Gaia architecture is the use of service workers. This isn't just to support offline for gaia apps, but also to support dynamic generation of page markup, and the ability to run logic in order to decide what resource to return for a given URL.

In order to make service workers work with the package update logic we should couple package update with service worker update. When the ServiceWorker spec require the browser to check for updates of, or download updates of, the ServiceWorker script, we instead update the full signed package.

This means that both when we do an "automatic" ServiceWorker update check, such as when the user visit a page which uses the ServiceWorker, and when the ServiceWorkerRegistration.update() function is called, that we update the full package rather than just the ServiceWorker script.

Once a new package has been downloaded, we go through the normal ServiceWorker update cycle. I.e. Gecko fire both "install" and "activate" events on the ServiceWorker. This will happen any time that a package is updated, even if the contents of the ServiceWorker script hasn't changed.

Gecko need to still serve the previous package content until the "activate" event for the new ServiceWorker version fires. I.e. until the new version has been installed, the old version of the package needs to be served for any network requests.

Issue: How do we enable the newly installing serviceworker to load content from the new package version, even though the previous package version is the one pinned in the cache.

Issue: Does CSP allow putting limits on where serviceworkers can be loaded from? We need to restrict ServiceWorkers scopes as well as script-urls to be from inside the package.

Origins and cookie jars - bug 1153435

The biggest change here is that we should stop always using different cookie jars for different apps. In particular normal unsigned content should always use the same cookie jar no matter where it was loaded.

However signed packages will get their own cookies and IndexedDB data. Content inside a signed package will not share cookies, IndexedDB data, etc with unsigned content from the same domain. It will also not share data with content from other signed packages from the same domain. This is to ensure that unsigned content from the same domain can't read for example sensitive data that the signed content has cached in IndexedDB. And to prevent unsigned content from writing into the localStorage that signed content uses and thereby tricking the signed content into performing unintended actions.

However when pages from inside a signed package makes network requests to other websites, it should still use the normal cookies from those websites. And if a page from a signed package creates an <iframe> containing an unsigned website, then that website will be loaded with its normal cookies and will have access to its normal IndexedDB data.

In other words, each signed package acts like a separate website. They do not act like a separate "world"/"context".

The way that we will implement this is by generalizing the current appId and isInBrowserElement mechanism. We will introduce a OriginAttributes struct which will hold the "cookie jar" that is used for a given web page. We can then write policies for which parts of this struct is inherited into iframes, and which parts do not. The nsIPrincipal interface will contain one of these structs. We will also have functions for serializing this struct to a string, and for parsing such a string back into a struct.

Most code will treat this OriginAttributes struct as an opaque value. When we store data we store, as part of the key, the serialization of the OriginAttributes.

Two pages will only be considered same-origin if they have the same scheme+host+port, but also if all of the values inside the OriginAttributes of their nsIPrincipal have the exact same values.

We will then add a 'signedPkg' member to OriginAttributes. When a page is loaded from inside a signed package, we will read a package-identifier from inside the package and set it in the OriginAttributes of the nsIPrincipal of the page.

However, when we do the network request for the package itself, this is treated like other network requests to the webserver. I.e. the network request is considered as an unsigned request and so the normal cookies of the webserver is sent. We have to do it this way since when we fetch a signed package the first time, we don't know that the package is signed, and so we use the normal cookie jar for that domain.

The effect of this is that when we are making network requests, these are never affected by package signing. As mentioned above, requests for the package itself are not affected, and requests for pages inside the package don't send any cookies at all since they are simply loaded from the package.

However, when a page from a signed package access the document.cookies API, the cookies returned *do* use the full OriginAttributes. I.e. the document.cookies API is treated like other storage APIs like IndexedDB and localStorage.

Issue: Verify with Honza that this is is doable and not complex. It should hopefully be the most natural way to write the cookie code.

If any page does a XHR request to a URL inside a signed package this is treated like any other network request and is permitted. This doesn't expose any user-private information and simply returns content that resides on the server.

Implementation

Search for all the open nsec bugs: http://mzl.la/1SLAWum

  • P1: Milestone 1 (Sept 4)
  • P2: Milestone 2 (Oct 2)
  • P3: Feature complete (Nov 2)
  • P4: Post-2.5 release

Signing - bug 1153420

Full Query
ID Priority Summary Status Assigned to Resolution Milestone
1220025 P5 Tool to unpack streamable packages NEW No milestone

1 Total; 1 Open (100%); 0 Resolved (0%); 0 Verified (0%);


Verifying signatures - bug 1153422

Full Query
ID Priority Summary Status Assigned to Resolution Milestone
1178518 P2 Support for verifying signed packages RESOLVED Jonathan Hao (inactive) [:jhao] FIXED No milestone
1178525 P1 Ensure the package is verified before content is served RESOLVED Henry Chang [:hchang] FIXED No milestone
1178526 P1 Set appropriate origin attributes for signed packages RESOLVED Henry Chang [:hchang] FIXED No milestone
1178527 P1 cache the signature check so that we dont need to recheck everytime RESOLVED Henry Chang [:hchang] WONTFIX No milestone
1178539 P3 Allow users to manage permissions of web pages in FxOS NEW No milestone
1185439 P1 Packaged apps needs to know the header of the multipart'ed content RESOLVED Henry Chang [:hchang] FIXED No milestone
1188717 P2 Store necessary info to cache metadata for packaged web app RESOLVED Henry Chang [:hchang] INVALID No milestone
1214079 -- Doom all the cache of the signed packaged web app if it's not verified. RESOLVED Henry Chang [:hchang] FIXED No milestone
1217694 -- Signed package should come from the same origin as moz-package-origin specified in its manifest. RESOLVED Jonathan Hao (inactive) [:jhao] FIXED No milestone
1218284 -- Match signed packages' with trust origin without suffix RESOLVED Jonathan Hao (inactive) [:jhao] FIXED No milestone
1239559 -- Reuse SRI code in NSec verification RESOLVED Jonathan Hao (inactive) [:jhao] WONTFIX No milestone

11 Total; 1 Open (9.09%); 10 Resolved (90.91%); 0 Verified (0%);


CSP - bug 1153423

Full Query
ID Priority Summary Status Assigned to Resolution Milestone
1178556 P2 Ensure script-src 'self' is restricted to content inside the signed package RESOLVED Ethan Tseng [:ethan] WONTFIX No milestone
1179060 P2 Apply a default CSP for signed packaged content RESOLVED Ethan Tseng [:ethan] WONTFIX No milestone
1179061 P2 Create CSP tests for signed packages RESOLVED Ethan Tseng [:ethan] WONTFIX No milestone
1179062 -- investigate marketplace for apps that use CSP RESOLVED Christiane Ruetten [:cr] FIXED No milestone
1179064 P2 Ensure that service worker code for signed packages is contained within the package RESOLVED Dimi Lee[:dimi][:dlee] WONTFIX No milestone
1180637 -- Packaged Apps do not apply CSP RESOLVED Valentin Gosu [:valentin] FIXED No milestone
1181137 P1 Packaged Apps do not apply security headers RESOLVED Henry Chang [:hchang] FIXED No milestone

7 Total; 0 Open (0%); 7 Resolved (100%); 0 Verified (0%);


Process isolation - bug 1153428

Full Query
ID Priority Summary Status Assigned to Resolution Milestone
1170894 P1 Implement process switching for browser-element RESOLVED Kan-Ru Chen [:kanru] (UTC+8) FIXED No milestone
1180085 P3 Prevent signed packages from being framed cross-origin RESOLVED WONTFIX No milestone
1180087 P1 Switch privileged process when loading a page from a signed package RESOLVED Kan-Ru Chen [:kanru] (UTC+8) DUPLICATE No milestone
1180088 P1 Fix security checks so that they work without appid by tagging a child process with a package identifier. RESOLVED Henry Chang [:hchang] FIXED No milestone
1186290 P2 Notify TabParent to switch process when a signed packaged is loading from different origin. RESOLVED Henry Chang [:hchang] FIXED No milestone
1186294 P2 Allow sending a parent process initiated network load to child process RESOLVED INVALID No milestone
1186296 P1 Manage nsIBrowserElementAPI in TabParent RESOLVED Kan-Ru Chen [:kanru] (UTC+8) DUPLICATE No milestone
1186843 P2 Notify observers "message-manager-will-change" before switching processes RESOLVED Kan-Ru Chen [:kanru] (UTC+8) FIXED No milestone
1209662 P2 Support session history navigation between different processes for new security model process isolation ASSIGNED Kan-Ru Chen [:kanru] (UTC+8) No milestone
1214572 P2 Should use a new process to load content when loading from a signed packaged web app. RESOLVED Henry Chang [:hchang] WONTFIX No milestone
1216443 -- Navigating from "about:blank" to signed packaged web content doesn't trigger process switch. RESOLVED Henry Chang [:hchang] FIXED No milestone

11 Total; 1 Open (9.09%); 10 Resolved (90.91%); 0 Verified (0%);


Installing and updating - bug 1153432

Full Query
ID Priority Summary Status Assigned to Resolution Milestone
1178533 P1 Register permissions, system messages etc on navigation to signed packages RESOLVED Stephanie Ouillon [:arroway] FIXED No milestone
1178536 P2 Register web activities and system messages for signed packages when they are pinned RESOLVED Stephanie Ouillon [:arroway] WONTFIX No milestone
1180091 P2 make sure http cache follows normal HTTP semantics for signed packages RESOLVED Valentin Gosu [:valentin] WONTFIX No milestone
1180092 P1 implement cache-pinning of packages RESOLVED DUPLICATE No milestone
1180093 P2 connect gaia pinning with gecko cache-pinning for packages RESOLVED WONTFIX No milestone
1180094 P4 support differential package updates RESOLVED WONTFIX No milestone
1187156 P1 Figure out how web packaged app updating should work RESOLVED DUPLICATE No milestone
1190290 P2 Figure out updates of pinned packages RESOLVED Valentin Gosu [:valentin] WONTFIX No milestone
1195713 P1 [PackagedAppService] The package cache doesn't use correct nsILoadContextInfo RESOLVED Henry Chang [:hchang] FIXED No milestone
1202555 P2 [PackagedAppService] Copy headers from package to each subresource for signed package. RESOLVED Henry Chang [:hchang] WONTFIX No milestone
1206058 P2 Register app handlers (system msg) on navigation to signed packages RESOLVED Stephanie Ouillon [:arroway] DUPLICATE No milestone
1206059 -- Remove permissions registered on navigation to signed packages RESOLVED Stephanie Ouillon [:arroway] WONTFIX No milestone
1212223 -- nsMultiMixedConv might call |SendData| with incorrect buffer length RESOLVED Henry Chang [:hchang] FIXED No milestone
1212761 -- Delete all cached files when failing to verify the packaged web app RESOLVED DUPLICATE No milestone
1216062 -- Install packaged web app with package identifier taken into account. RESOLVED Henry Chang [:hchang] FIXED No milestone
1232898 -- Make manifest format comply with W3C WebApps NEW No milestone

16 Total; 1 Open (6.25%); 15 Resolved (93.75%); 0 Verified (0%);


Service Workers - bug 1153433

Full Query
ID Priority Summary Status Assigned to Resolution Milestone
1131322 -- Service Workers for Gaia RESOLVED WONTFIX No milestone
1181389 P2 check for full package update when doing service worker update RESOLVED Dimi Lee[:dimi][:dlee] WONTFIX No milestone
1181390 P2 fire install and activate events on service worker RESOLVED Dimi Lee[:dimi][:dlee] WONTFIX No milestone
1181391 -- Preserve previous package until activate event RESOLVED Dimi Lee[:dimi][:dlee] INVALID No milestone

4 Total; 0 Open (0%); 4 Resolved (100%); 0 Verified (0%);


Origins and cookie jars - bug nsec-origins

Full Query
ID Priority Summary Status Assigned to Resolution Milestone
1163254 P1 Add signedPkg OriginAttribute for new Firefox OS security model RESOLVED Henry Chang [:hchang] FIXED No milestone
1164292 -- Clean up various CAPS pieces and make nsExpandedPrincipal::origin do something useful RESOLVED Bobby Holley (:bholley) FIXED No milestone
1164977 -- Consolidate subsumes checks and attribute handling onto BasePrincipal RESOLVED Bobby Holley (:bholley) FIXED No milestone
1165162 -- Include all non-default app attributes in stringified nsIPrincipal::origin RESOLVED Bobby Holley (:bholley) FIXED No milestone
1165214 -- DOMStorageManager should use origin for ScopeKey and QuotaKey RESOLVED Honza Bambas (:mayhemer) FIXED No milestone
1165217 -- Use origin attribute in nsIUsageCallback RESOLVED Nika Layzell [:mystor] FIXED No milestone
1165219 -- Use origin in ManagerId RESOLVED Steven Englehardt [:englehardt] DUPLICATE No milestone
1165224 -- Use origin in QuotaManager RESOLVED DUPLICATE No milestone
1165256 P2 use origin for app_cache RESOLVED Honza Bambas (:mayhemer) FIXED No milestone
1165263 -- Use origin for nsIPermissionManager RESOLVED Nika Layzell [:mystor] FIXED No milestone
1165267 P1 Use OriginAttributes for nsCookieService RESOLVED Ethan Tseng [:ethan] FIXED No milestone
1165269 P2 Use origin for http cache RESOLVED Honza Bambas (:mayhemer) FIXED No milestone
1165270 -- Use origin for BroadcastChannel RESOLVED Andrea Marchesini [:baku] FIXED No milestone
1165272 -- unify Get*CodebasePrincipal with createCodebasePrincipal in nsIScriptSecurityManager RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1165277 -- Use origin in SessionStorage.jsm RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1165466 P2 Fix up docshell and loadcontext inheriting code in nsIScriptSecurityManager to use originAttributes rather than explicitly querying appid/browser RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1165787 -- Use origin in RequestSyncService.jsm RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1167098 P2 IPC change for the new FirefoxOS security model RESOLVED WONTFIX No milestone
1167100 -- User nsIPrincipal.originAttribute in ContentPrincipalInfo RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1168300 -- Add cookieJar attribute and notify clear-cookiejar-data RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1168777 P2 remove mozIApplicationClearPrivateDataParams RESOLVED Yoshi Huang [:allstars.chh], Inactive WONTFIX No milestone
1172080 -- Using an optional '!' in a principal's origin to denote extra data is spoofable RESOLVED Nika Layzell [:mystor] FIXED No milestone
1179985 P2 [meta] Make all Origin-Related APIs OriginAttributes-aware RESOLVED FIXED No milestone
1182347 -- Eliminate nsIPrincipal::cookieJar RESOLVED Bobby Holley (:bholley) FIXED No milestone
1188776 -- Remove appId/isInBrowserElement from BroadcastChannel RESOLVED Andrea Marchesini [:baku] FIXED No milestone
1188777 -- e10: use originAttributes from child to parent process. RESOLVED Yoshi Huang [:allstars.chh], Inactive INVALID No milestone
1191653 -- Listen to clear-origin-data in nsPermissionManager.cpp RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1191740 -- Add OriginAttributes in TabContext RESOLVED Kan-Ru Chen [:kanru] (UTC+8) FIXED No milestone
1195930 P1 Use origin in QuotaManager RESOLVED Jan Varga [:janv] FIXED No milestone
1196644 P2 Add OriginAttributes to PermissionSettings RESOLVED Stephanie Ouillon [:arroway] WONTFIX No milestone
1196665 -- Add originAttributes into SpecialPowers RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1197093 -- add originAttributes to nsIOfflineCacheUpdate RESOLVED Honza Bambas (:mayhemer) DUPLICATE No milestone
1201042 P1 Update HTTP cache index format to work with OriginAttributes' suffix RESOLVED Michal Novotny (:michal) FIXED No milestone
1209162 -- Create OriginAttributes subtypes for different uses and define conversion routines between them RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1209349 -- Audit the callers of the two-argument OriginAttributes constructor RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1210890 -- Create signedpackage inBrowser origin attribute to fix mozBrowser API in signed packages RESOLVED INVALID No milestone
1210903 -- Modify cookie behavior for signed packages RESOLVED INVALID No milestone
1212250 -- Use InheritFromDocToChildDocshell in TabContext when inheriting OriginAttributes from parent window RESOLVED DUPLICATE No milestone
1213577 -- Use OriginAttributes in nsHttpAuthManager RESOLVED Honza Bambas (:mayhemer) FIXED No milestone
1214071 P1 Add APIs get/removeCookiesWithOriginAttributes() in nsICookieManager2.idl RESOLVED Jonathan Hao (inactive) [:jhao] FIXED No milestone
1225053 -- gfxSVGGlyphs.cpp should use correct origin attributes to create principal RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1225349 -- PrincipalOriginAttributes should inherit mSignedPkg accordingly by URI RESOLVED WONTFIX No milestone
1225353 -- DocShell/NeckoOriginAttributes should inherit mSignedPkg accordingly by mSignedPkgInBrowser RESOLVED WONTFIX No milestone
1227861 -- Add OriginAttributes getter/setter into nsIDocShell RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1230459 -- Use InheritFromDocToChildDocShell in LoadContext RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1233136 -- Audit all "clear-origin-data" consumers NEW No milestone
1237152 -- rename "clear-origin-data" RESOLVED Yoshi Huang [:allstars.chh], Inactive FIXED No milestone
1267910 P1 Make the API add() and getCookiesFromHost() of the nsICookieManager2 OriginAttributes-aware RESOLVED Tim Huang[:timhuang] FIXED No milestone

48 Total; 1 Open (2.08%); 47 Resolved (97.92%); 0 Verified (0%);


2.5 Sprint Status

Meeting Note

References