1. Introduction
Throughout its existence the web has been evolved into an increasingly capable application platform. Secure Contexts formalize transport security, Cross Origin Isolation mitigates side-channel attacks, and browsers and operating systems have experimented with permission interfaces based on selecting particular files and devices to make access more scoped and understandable to users. Each of these advancements either improved the safety guarantees of the web platform, or guided users towards a more accurate expection of a page’s behavior, and unlocked new classes of capabilities that could be brought safely to the web.
Despite these advancements, there are some APIs that still cannot safely be exposed to the web because they violate the web’s security primitives in a way that cannot reasonably be addressed, or cannot be explained clearly enough for users to make an informed decision about whether or not to grant a site access to them. If the platform cannot prove that exposing an API to a particular site is safe, then trust must derive from external attestations.
Any assertion about the safety or behavior of a page requires knowing the contents and behavior of the page; attestations are only meaningful if the code that was vouched for is the same code being executed. Because of this, any system that delegates trust decisions must be able to verify the integrity of the code it is running — it must know that it matches the code that was delegated trust.
Additionally, capabilities that don’t fit within the web’s current security model have the potential to pose a risk to other web content. This risk is bidirectional: sandbox-piercing capabilities could be used to attack other sites, and having access to powerful capabilities makes a site a more attractive target for bad actors. To mitigate these risks, any content that is granted access to a capability through the mechanisms described in this specification must be isolated from a user’s normal browsing session.
This specification defines Isolated Contexts, which are environments that meet a minimum standard of integrity and isolation, and provide a means of auditing web content for the purpose of trustworthiness attestation, and isolate this content from the rest of the user’s browsing data.
While this specification focuses on user-agent provided capabilities, Isolated Contexts could be beneficial for any web page functionality whose threat model isn’t satisfied by the web’s security model. For example, the threat model of some end-to-end encrypted chat applications includes server compromise, which is not protected against by the web today. The auditability and attestation enabled by Isolated Contexts could allow these applications to have confidence in the integrity and providence of the code they are running.
2. Isolated Contexts
Isolated Contexts are defined through a series of § 3 Monkey Patches to existing specifications.
Integrity is verified through a combination of strict [CSP], which ensures cross-origin executable content cannot be loaded, and an integrity verification algorithm, which is an abstract mechanism to validate content loaded within a page. This specification does not mandate a specific validation approach, it only defines how one would be used to determine if an environment is an Isolated Context.
2.1. Which APIs should require an Isolated Context?
As few as possible. Any API that can only be exposed to Isolated Contexts very likely violates at least one design principle of the web, most commonly that it should be safe to visit a web page. Before requiring an Isolated Context to use an API, consider the following questions:
-
Is a new Web Platform API the only way to address the problems this API is trying to solve? Web Extensions and native applications have their place.
-
If a capability cannot be communicated clearly to users, is there another way to solve the problem that would be more understandable to users, and allow them to make informed decisions about what content can access it?
-
Can the scope of the API be reduced such that it no longer poses an unacceptable risk if exposed to an average web page?
If no alternative can be found, requiring an API to run within an Isolated Context can be considered as a last resort.
Part of what makes the web such a unique and successful platform is its lack of gatekeepers. Anyone can purchase a domain name and host their content without anyone else’s approval, and with full access to the Web Platform’s API surface; everyone has equal footing. The security guarantees provided by Isolated Contexts enable auditability, which in turn enables attestation. The safety provided by attestation, either by the browser vendor or a third-party, is the main reason an API would be restricted to Isolated Contexts. Parties providing attestation services have the potential to become gatekeepers to the Web Platform, which is not a desirable direction for the platform to move. Browser vendors must be extremely selective about which APIs they allow in Isolated Contexts; changing an API so it can be used in a Secure Context should be strongly preferred whenever possible.
2.2. UI Treatment
This specification focuses on the technical requirements needed to achieve integrity and isolation, but if Isolated Contexts are being used to enable powerful capabilities, it is also critical to not violate user expectations.
Users trust the web because they’ve been taught that web pages are safe, have limited access to their device, and that they are in control of this access. All APIs on the Web Platform have been carefully designed towards this end, with a goal of ensuring that it should be safe to visit a web page.
Browser vendors should consider whether capabilities restricted to Isolated Contexts would violate a user’s expectation of what a web page is capable of doing. Violating these expectations would not only damage trust in the site, but has the risk of damaging a user’s trust in the Web Platform as a whole.
To mitigate this, steps should be taken by the user agent to convey to users that content running within an Isolated Context is not typical web content. This could involve an installation flow, or a Web App UI treatment.
3. Monkey Patches
This specification makes the following monkey patches to existing specifications:
-
Patches to [CSP] will define the characteristics of a policy that’s robust enough to meaningfully defend against attack, and enforce that cross-origin content cannot be loaded. It builds on what we’ve learned from explorations like [strict-csp] and [securer-contexts], pushing developers towards well-understood and valuable defenses.
-
Patches to [HTML] will define the ways in which those CSP characteristics, along with other security requirements, are evaluated within a given context, similar conceptually to secure context and cross-origin isolated capability. It will additionally define user agent properties needed to verify the integrity of an origin's resources.
-
Patches to [FETCH] will add integrity verification to the fetch algorithm.
-
Patches to [WEBIDL] will define the
[IsolatedContext]
attribute, and the way it relies on the changes above to control the exposure of a given WebIDL construct. -
Patches to [STORAGE] will define the double-keying requirements of Isolated Contexts.
3.1. Content Security Policy
In [CSP], we’ll define an algorithm for evaluating the strength of the amalgamation of policies contained within a CSP list. We’ll define a few supporting algorithms as well, but § 3.1.1 Does a policy meaningfully mitigate injection attacks? is the core entry point CSP will expose to HTML.
3.1.1. Does a policy meaningfully mitigate injection attacks?
Meaningful
". Possible return values are "Meaningful
" and
"Not meaningful enough
".
-
Let meets object requirements, meets base requirements, meets script requirements, meets style requirements, meets subresource requirements, and meets trusted type requirements be booleans whose values are
false
. -
For each policy in policies:
-
If policy’s disposition is not "
enforce
" or policy’s source is not "header
", continue. -
If policy sufficiently mitigates plugins, set meets object requirements to
true
. -
If policy sufficiently mitigates relative URL manipulation, set meets base requirements to
true
. -
If policy sufficiently mitigates script execution, set meets script requirements to
true
. -
If policy sufficiently mitigates style evaluation, set meets style requirements to
true
. -
If policy sufficiently blocks insecure subresources, set meets subresource requirements to
true
. -
If policy sufficiently mitigates DOM sinks, set meets trusted type requirements to
true
.
-
-
Return "
Meaningful
" if meets object requirements, meets base requirements, meets script requirements, meets style requirements, meets subresource requirements, and meets trusted type requirements are alltrue
. -
Return "
Not meaningful enough
".
3.1.2. Obtain the active directive for a type
-
Let fallback chain be the result of executing Get fetch directive fallback list on directive name.
-
For each name in fallback chain:
-
If policy’s directive set contains a directive directive whose name is name, return directive.
-
-
Return null.
3.1.3. Does a policy sufficiently mitigate plugins?
Sufficient
". Possible return values are
"Sufficient
" and "Not sufficient
".
3.1.4. Does a policy sufficiently mitigate relative URL manipulation?
Sufficient
".
Possible return values are "Sufficient
" and "Not sufficient
".
-
For each directive in policy’s directive set:
-
Return "
Not sufficient
".
3.1.5. Does a policy sufficiently mitigate script execution?
Sufficient
".
Possible return values are "Sufficient
" and "Not sufficient
".
-
Obtain active directive from policy, given "
script-src
". -
Return "
Sufficient
" if all of the following are true:-
active directive is not null
-
All source expressions in active directive are an ASCII case-insensitive match for the strings "
'none'
", "'self'
", or "'wasm-unsafe-eval'
".
-
-
Return "
Not sufficient
".
3.1.6. Does a policy sufficiently mitigate style evaluation?
Sufficient
".
Possible return values are "Sufficient
" and "Not sufficient
".
-
For each directive in policy’s directive set:
-
Obtain active directive from policy, given "
style-src
". -
Return "
Sufficient
" if all of the following are true:-
directive’s name is "
style-src
". -
All source expressions in active directive are an ASCII case-insensitive match for the strings "
'none'
", "'self'
", or "'unsafe-inline'
".
-
-
-
Return "
Not sufficient
".
3.1.7. Does a policy sufficiently block insecure subresources?
Sufficient
".
Possible return values are "Sufficient
" and "Not sufficient
".
-
For each directive name in the set [
frame-src
,connect-src
,img-src
,media-src
,font-src
]:-
Obtain active directive from policy, given directive name.
-
Return "
Not sufficient
" if any source expression in active directive is not an ASCII case-insensitive match for the strings "'none'
", "'self'
", "https:
", "blob:
", or "data:
".
-
-
Return "
Sufficient
"
3.1.8. Does a policy sufficiently mitigate DOM sinks?
Sufficient
".
Possible return values are "Sufficient
" and "Not sufficient
".
-
For each directive in policy’s directive set:
-
Return "
Sufficient
" if all of the following are true:-
directive’s name is "
require-trusted-types-for
". [TRUSTED-TYPES] -
directive’s value contains[0] an ASCII case-insensitive match for the string "
'script'
".
-
-
-
Return "
Not sufficient
".
3.1.9. Example
The following CSP meaningfully mitigates injection attacks:
base-uri 'none'; default-src 'self'; object-src 'none'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src 'self' https: blob: data:; connect-src 'self' https: blob: data:; img-src 'self' https: blob: data:; media-src 'self' https: blob: data:; font-src 'self' blob: data:; require-trusted-types-for 'script';
3.1.10. Does a policy meaningfully mitigate UI Redressing attacks?
Meaningful
".
Possible return values are "Meaningful
" and "Not meaningful enough
".
-
For each policy in policies:
-
If policy’s disposition is not "
enforce
" or policy’s source is not "header
", continue. -
For each directive in policy’s directive set:
-
-
Return "
Not meaningful enough
".
3.2. HTML
In HTML, we’ll define a few properties used for resource integrity verification, and some algorithms used in combination with those defined in § 3.1 Content Security Policy to define characteristics of the environment settings object. These characteristics will be examined from [WEBIDL] when determining whether or not a given IDL construct is exposed on the associated global object.
3.2.1. Integrity
An integrity verification algorithm is an implementation-defined algorithm that accepts a request and a response, and returns a boolean.
Note: A typical integrity verification algorithm might verify that a response body hashes to an expected value, or that it originated from a known bundle of resources.
A user agent holds an origin integrity verification map, which is a map of tuple origins to integrity verification algorithms.
Note: How user agents populate the origin integrity verification map is outside the scope of this specification, which is focused on the properties needed to establish integrity and isolation. Isolated Web Apps provide one possible implementation by basing this map on the set of installed Isolated Web Apps.
3.2.2. Environment Settings Object properties
Note: Because the definition of meaningful injection and UI Redressing mitigation for a CSP list depends only upon the header-delivered policies, these properties will not mutate during an environment’s lifetime.
true
:
-
If environment does not meaningfully mitigate injection attacks, return
false
. -
If environment’s cross-origin isolated capability is not concrete, return
false
. -
If environment does not mitigate UI Redressing attacks, return
false
. -
Let origin be environment’s origin.
-
If the user agent's origin integrity verification map[origin] does not exist, return
false
. -
Return
true
.
3.3. Fetch
In Fetch, we’ll use the integrity verification algorithm defined in § 3.2.1 Integrity to verify that responses have the expected contents.
3.3.1. Verify the integrity of a response
not applicable
", "invalid
", or "valid
".
- Let client be request’s client.
- If client is
null
, return "not applicable
". - Let origin be request’s origin.
- If the user agent's origin integrity verification map[origin]
does not exist, return "
not applicable
". - Let integrity verification algorithm be the user agent's origin integrity verification map[origin].
- If response’s body is
null
, return "invalid
". - If the result of executing integrity verification algorithm given request and response is
false
, return "invalid
". - Return "
valid
".
3.3.2. Patches to the "Main Fetch" algorithm
The main fetch algorithm is extended as follows:- Let request be fetchParams’s request.
- Let response be
null
. -
If request’s integrity metadata is not the empty string, then:
- ...
-
If the result of executing verify the integrity of a response given request and response is "
invalid
", then run fetch response handover given fetchParams and a network error. - Otherwise, run fetch response handover given fetchParams and response.
NOTE: Ideally we would integrate integrity verification with [SRI]'s integrity metadata and its supporting algorithms. That would require a non-trivial refactoring of how the [SRI] specification handles integrity metadata strings, which may be worth pursuing in the future.
3.4. WebIDL
In WebIDL, we’ll define the [IsolatedContext]
attribute, and wire it up to
the hook created in HTML above:
3.4.1. [IsolatedContext]
If the [IsolatedContext
] extended attribute appears on an interface, partial interface, interface mixin, partial interface mixin, callback interface, namespace, partial namespace, interface member, interface mixin member, or namespace member,
it indicates that the construct is exposed only within an isolated context.
The [IsolatedContext
] extended attribute must not be used
on any other construct.
The [IsolatedContext
] extended attribute must take no arguments.
If [IsolatedContext
] appears on an overloaded operation,
then it must appear on all overloads.
The [IsolatedContext
] extended attribute must not be specified on more
than one of the following:
-
an interface member and its interface or partial interface;
-
an interface mixin member and its interface mixin or partial interface mixin;
-
a namespace member and its namespace or partial namespace.
Note: This is because adding the [IsolatedContext
] extended attribute on a member when its containing definition is also annotated with the
[IsolatedContext
] extended attribute does not further restrict the
exposure of the member.
An interface without the [IsolatedContext
] extended attribute must not inherit from another interface
that does specify [IsolatedContext
].
3.4.2. Patches to the "exposed" algorithm
WebIDL’s exposed algorithm is adjusted as follows, adding a single step
after similarly handling [CrossOriginIsolated
] (step 4 below).
- If construct’s exposure set is not
*
, and realm.[[GlobalObject]] does not implement an interface that is in construct’s exposure set, then return false. - If realm’s settings object is not a secure context, and construct is conditionally exposed on [
SecureContext
], then return false. - If realm’s settings object's cross-origin isolated capability is false,
and construct is conditionally exposed on [
CrossOriginIsolated
], then return false. -
If realm’s settings object is not an isolated context,
and construct is conditionally exposed on [
IsolatedContext
], then returnfalse
. - Return true.
3.5. Storage
The obtain a storage key for non-storage purposes algorithm is extended to require double-keying on all storage belonging to an environment with a top-level origin known by the user agent to have an integrity verification algorithm.
- Let origin be environment’s origin if environment is an environment settings object; otherwise environment’s creation URL's origin.
- Let top-level origin be environment’s top-level origin.
- If the user agent's origin integrity verification map [top-level origin] exists, return a tuple consisting of top-level origin and origin.
- Return a tuple consisting of origin.
Note: This is essentially a minimally-specified version of Client-Side Storage Partitioning. When that is fully specified and merged into the necessary specifications, those changes will supersede this section, and it can be removed.