Authors of security-critical applications want the web’s low-friction install process, its linkability, and its cross-platform nature, but are understandably nervous about hosting very powerful applications on the web alongside malicious content that can attack in any number of ways. For example, malicious content can:
Exploit cross-site scripting (XSS) or cross-site request forgery (CSRF) vulnerabilities to steal sensitive user data or take actions on a user’s behalf.
Trick the user into revealing data or taking actions via clickjacking attacks.
Navigate a security-critical application to a phishing page without the user’s knowledge, and then trick the user into leaking sensitive data.
It may not make sense to describe Isolation as mitigating phishing scenarios like this. It may indeed do so, but it’s not the primary goal.
Leverage a browser vulnerability to gain access to data from other origins (universal XSS or UXSS).
Security-critical applications should be able to run in a browser with a degree of isolation that mitigates these attacks. This specification defines an isolation mechanism that an origin can opt in to, thereby reducing its exposure to other web content. Developers responsible for security-critical web applications can choose to trade away some of the features of being on the open web (such as full linkability) in exchange for better protection from malicious web content.
Given that a navigation manager enables linkability, it may not make sense to suggest there is a necessary tradeoff, at least in this respect.
1.1. Threat Model
We consider a security-critical application,
very-important.example, whose developers want to
isolate it from regular web content like
evil.example. We assume that
a large, complicated site with many developers, some of whom occasionally make mistakes, such as
accidentally opening up a reflected XSS vulnerability. We also assume that the user does not know
evil.example is evil, and also that the user is not necessarily a power user; thus the user
does not necessarily take precautions such as using
separate profiles or browsers. In our threat model,
evil.example might try to attack
very-important.example in a number of ways which this document aims to address:
evil.examplemight cause the user’s browser to send a request to
very-important.examplethat exploits a cross-site scripting (XSS) or cross-site request forgery (CSRF) vulnerability. Such vulnerabilities might be triggered by navigational requests (via
open()), or by subresource requests (via
very-important.examplemight open a link to
evil.example(for example, user-generated content could include an auto-linked reference to that origin, or a content write posted a link to
evil.examplewithout knowing that it is evil). This allows
evil.exampleto obtain a reference to the
very-important.examplewindow via the
window.openerattribute, which opens up communication channels (
postMessage(), frame counting and traversal, navigation of the
very-important.examplewindow, etc.) that
very-important.examplemight not be expecting.
evil.examplecan obtain such a reference via
evil.examplemight exploit a vulnerability in the browser itself (UXSS) to gain access to
very-important.exampledata and cookies.
Note: The mechanism proposed in this document does not aim to give hard guarantees about protection from UXSS, but does hope to mitigate some of the risks on a best-effort basis.
evil.examplemight be able to extract data from
very-important.exampleby loading its resources or framing its content. Extraction techniques could range from exploitation of overly-broad CORS headers, to timing attacks like [HEIST], [PIXEL-PERFECT], etc.
Maybe mention that this would be facilited by ambient authority?
very-important.examplemight embed resources from other origins (e.g.,
investments-r-us.biz), where the user becomes authenticated with
investments-r-us.bizby authenticating with
evil.examplemight then be able to extract
very-important.exampleuser data from
investments-r-us.biz, even if it can’t attack
very-important.examplemight in fact be
very-important.something.example, in which case:
evil.something.examplemight try to set a cookie for all of
something.examplein hopes that it can fix a session or CSRF token for the user on
evil.something.examplemight take advantage of
very-important.something.example's (ill-advised) loosening of the same-origin policy via
1.2. Mitigation Strategy
To address the threats above, this document details an origin-wide isolation mechanism that aims to
break the communication channels between
very-important.example opts-in to this mechanism, the user agent will enforce the following:
very-important.examplemay not be framed by cross-origin contexts. That is, the user agent will act as though
Content-Security-Policy: frame-ancestors 'self'is delivered with each resource. This prevents
evil.examplefrom exploiting attacks that require control over
very-important.example's browsing context ([PIXEL-PERFECT], as well as straightforward clickjacking), or access to
Cross-origin resources framed by
very-important.exampleare not given access to
window.parent(those accessors will return
null). This prevents
evil.examplefrom exploiting attacks which require access to
Window, or navigating the user to an unexpected URL to replace
very-important.examplein the top-level browsing context.
very-important.exampleopens a new, cross-origin window (via
<a target="_blank">...</a>, etc.), the new window will disown its opener, and the call to
null. That is, the user agent will act as though noopener is specified on outgoing links and
All cookies set by
very-important.examplewill be forced to be strict same-site cookies. This prevents
evil.examplefrom initiating authenticated requests to
very-important.example. Further, all cookies set on
very-important.example(including cookies set by responses to cross-origin requests) will be double-keyed and not sent on requests that occur outside the isolated context. This prevents
evil.examplefrom attacking ambient authority granted to
very-important.example's cross-site dependencies by virtue of being embedded in
Navigation into the isolated origin will be regulated by a navigation manager. Code from the isolated origin will get to validate each navigation before allowing it to proceed.
The user agent should load
very-important.exampleinto a separate process from other web content, including cross-origin content that it embeds, if possible.
Note: This is not a firm guarantee (especially since not all browsers implement per-site process isolation at all), but rather a best-effort attempt to mitigate the risks of UXSS bugs.
2. Key Concepts
An isolated origin is an origin that has opted in to isolate itself from other origins on the web, using the mechanisms defined in this specification.
User agents have an isolated origin store, which is a list of isolated origins.
When asked if an origin is isolated, an isolated origin store will return true if the given origin appears in its list, and false otherwise.
Expand to have an expiration time for each isolated origin in the store.
3. Opting into isolation
Isolated origins are defined by an isolation HTTP response header. The syntax for the name and value of the header are described by the following ABNF grammar [RFC5234]:
"Isolation:" *WSP "1" *WSP
Add a max-age
§5.3.2 Processing isolation headers describes how the isolation header is processed.
the isolate-me HTTP header needs to be sent and/or processed before the Set-Cookie header...
4. Controlling navigations
An isolated origin can use a service worker to perform security checks on navigations. By default, every navigation to an isolated origin fails, unless the origin has a service worker which explicitly allows it.
§5.3.1 Navigation checks and §5.1.5 Process a navigate response describe how the Fetch and HTML specs are modified to fail navigations to an isolated origin unless a service worker has performed security checks on them.
5.1. Integration with HTML
The HTML concept of origin should be expanded to contain a boolean isolated getter. This getter returns true if the origin is isolated and false otherwise.
The same origin check should be modified to return false if
A is isolated but
B is not, or vice versa.
Justify why the isolated flag does not need to be serialized
5.1.2. Cross-origin framing of isolated origins
Isolated origins should not be framed by cross-origin content. Step 1 of Process a navigate response should be modified to call §6.1 Should navigation response in target be blocked?.
5.1.3. Disowning isolated openers
When an isolated origin opens a new window to a different origin, that origin should not be able to
manipulate the isolated origin via the
Initializing a new Document object should be modified to call §6.2 Disown an isolated opener on browsingContext and the response used to generate the document.
5.1.4. Removing cross-origin subframe references
When an isolated origin embeds cross-origin subframes, those subframes should not be able to obtain
references to the isolated origin’s window via
window.top attribute algorithm should be modified to return
context's top-level browsing context’s active document’s origin is an isolated origin.
window.parent attribute algorithm should be
modified to return null if
context's top-level browsing context’s active document’s origin is an isolated origin.
5.1.5. Process a navigate response
Process a navigate response should be modified to fail a navigation to an isolated origin if it has not been explicitly allowed by a service worker for that origin. Specifically, Step 1 should be modified to include the condition:
response’s url’s origin is an isolated origin and request’s allow isolated navigation flag is unset.
5.2. Integration with Cookies
This section defines modifications to [COOKIES] to support isolated origins.
5.2.1. Forcing cookies to be same-site
Forcing cookies from isolated origins to be same-site means that an attacker cannot initiate an authenticated request from a victim’s browser to an isolated origin.
When receiving a cookie string on a request whose initiator’s origin is isolated, if the request’s origin is same origin with the
initiator’s origin, Section 5.3 should be modified to set the cookie’s
samesite-flag field to "Strict".
5.2.2. Double-keyed storage
When a cookie is set on a request for which the top-level document is an isolated origin, the cookie should be double-keyed, such that the cookie is only sent on requests initiated by contexts in which the top-level document is the same isolated origin. This prevents attackers from attacking ambient authority that an isolated origin’s cross-site dependencies obtain by virtue of being embedded in the isolated origin.
This section defines modifications to [COOKIES] to support these double-keyed cookies.
188.8.131.52. Storage model
The storage model of [COOKIES] should be updated to keep track of when cookies are set in a
top-level isolated origin as follows. Section 5.3 of [COOKIES] should be modified to store an
isolated-origin field for each cookie. When processing a cookie, if the request has a non-null client, then let
top origin be the origin of
the request’s client’s responsible browsing context’s top-level browsing context’s active Document. If
top origin is an isolated origin, then then the user agent should set the
isolated-origin cookie field to
top origin. Otherwise, the user agent should set the
field to the empty string.
define this section for Worker-based requests
184.108.40.206. The Cookie header
[COOKIES] should be updated to ensure that cookies that were set on an isolated origin are not sent in other contexts outside that origin. In other words, Section 5.4 of [COOKIES] should be modified to add the following to the list of requirements in step 1:
If the cookie’s
isolated-originfield is not the empty string, then the request must have a non-null client whose responsible browsing context’s top-level browsing context’s active Document’s origin is an isolated origin and is same origin with the cookie’s
these cookie changes don’t prevent all session fixation attacks. If a user has never visited victim.example.com before, evil.example.com can set a cookie for .example.com, which will be sent on the request when the user first navigates to victim.example.com. The isolated origin can mitigate this by using __Host- cookies for sensitive cookies. Maybe isolated origins should be required to use __Host- on all cookies.
5.3. Integration with Fetch
5.3.1. Navigation checks
The Fetch spec should be modified to give request a boolean allow isolated navigation flag, which is false by default. This flag is checked on navigations to isolated origins in §5.1.5 Process a navigate response.
The Request class should be modified to have an
allowIsolatedNavigation() method, which, when invoked, must run
Let origin be current settings object’s origin.
If origin is not same origin with request’s current url’s origin, then abort these steps.
should this throw an exception instead?
Set request’s allow isolated navigation flag to true.
NOTE: A service worker or a consumer of the Fetch API must call allowIsolatedNavigation() on a Request in order for a navigation to an isolated origin to be allowed.
Does this allow for navigation requests to redirect to isolated origins? Do we want it to?
5.3.2. Processing isolation headers
Fetch should be updated to call §6.3 Isolate an origin on response after Step 13 of HTTP-network fetch.
6.1. Should navigation response in target be blocked?
This algorithm is used to block cross-origin framing of isolated origins. Given a response (navigation response) and a browsing context (target), this algorithm returns "
if navigation response is from an isolated origin and one or more of the ancestors of target is
If target is not a nested browsing context, return "
If navigation response’s url’s origin is not an isolated origin, then return "
Let current be target.
Let navigation origin be a copy of navigation response’s url’s origin. Set navigation origin’s isolated flag to true.
While current has a parent browsing context (parent):
Set current to parent.
Let origin be current’s active document’s relevant settings object’s origin.
If origin is not same origin with navigation origin, return "
6.2. Disown an isolated opener
Given a browsing context (browsingContext) and a response (response) used to generate a document, this algorithm disowns browsingContext’s opener if the opener is an isolated origin.
If browsingContext does not have an opener browsing context, then abort these steps.
Let openedOrigin be a copy of response’s url’s
Let openerOrigin be browsingContext’s opener browsing context’s active document’s relevant settings object’s origin.
If openerOrigin is not an isolated origin, abort these steps.
If openedOrigin is same origin with openerOrigin, then abort these steps.
browsingContext should disown its opener.
6.3. Isolate an origin
This algorithm is called from HTTP-network fetch to process an isolation header on a response response.
If extracting header list values given isolation and response’s header list returns null, then abort these steps.
Let origin be response’s url’s origin.
If origin is not an isolated origin, set request’s allow isolated navigation flag to true.
NOTE: This step ensures that the first navigation to an isolated origin is allowed.
Add origin to the user agent’s isolated origin store.
parse and process max-age