1.Introduction
This section is not normative.
Modern Web applications are conglomerations of JavaScript written by multiple authors. Authors routinely incorporate third-party scripts into their applications and share user data with third-party services (e.g., as part of amashup). Unfortunately, in the existing model, the user’s data confidentiality and integrity is put at risk when one incorporates untrusted third-party code or shares data with untrusted third-party services.
Mechanisms such as CORS and CSP can be used to mitigate these risks by giving authors control over whom they share data with. But, once data is shared, these mechanisms do not impose any restrictions on how the code that was granted access can further disseminate the data.
This document specifies an extension to the current model called Confinement with Origin Web Labels (COWL). COWL provides authors with APIs for specifying (mandatory) access control policies on data, including content, in terms oforigin labels. These policies are enforced in a mandatory fashion, transitively, even once code has access to the data. For example, with COWL, the author ofhttps://example.com
can specify that a password is confidential tohttps://example.com
(and thus should only be disclosed tohttps://example.com
) before sharing it with a third-party password strength checking service. In turn, COWL ensures that the third-party service, which necessarily computes on the sensitive password, is confined and respects the policy on the password: COWL disallows it from disclosing the password to anyorigin other thanhttps://example.com
.
COWL enforces such policies by confining code at thecontext-level, according to the sensitivity (i.e., the label) of the data the code has observed. To reap the greatest benefits of COWL, authors will need to compartmentalize applications into multiple contexts (e.g.,iframes).
In the existing model, any page served from an origin has the ambient, implicit authority of that origin. This documents generalizes this notion of authority and gives authors explicit control over it withprivileges. For example, by default, a page whose origin ishttps://example.com
has the privilege forhttps://example.com
. This gives the page the authority to arbitrarily disseminate data sensitive tohttps://example.com
; to be backwards-compatible, the page is not confined when reading data sensitive tohttps://example.com
. However, COWL allows the author to run the page with "weaker"delegated privileges (e.g., one corresponding the current user athttps://example.com
) or to drop the privilege altogether.
COWL is intended to be used as a defense-in-depth mechanism that can restrict how untrusted—buggy but not malicious—code handles sensitive data. Given the complexities of browser implementations and presence of covert channels, malicious code may be able to exfiltrate data. Authors should still use discretionary access control mechanisms, such as CSP and CORS, to restrict access to the data in the first place.
1.1.Goals
The goal of COWL is to provide authors with a means for protecting the confidentiality and integrity of data that is shared with untrusted code, whether third-party or their own. Existing mechanisms (e.g., CORS’sAccess-Control-Allow-Origin
header and thetargetOrigin
argument topostMessage()
) provide a way for restricting whichorigins may access the shared data. But, once content has access to data it can usually disseminate it without restrictions. While CSP can be used to confine code, i.e., restrict how confidential data is disseminated, setting a correct CSP policy (as to confine code) is difficult and limited to content the author has control over. Indeed, sharing confidential data in the existing model almost always requires the sender to trust the receiver not to leak the data, accidentally or otherwise. COWL provides a defense-in-depth option for protecting data confidentiality and integrity. In particular, with COWL:
Authors should be able to specify confidentiality and integrity policies on data in terms of origin labels: the origins to whom the data is confidential and the origins that endorse the data. This allows authors to share sensitive data with third-party content and impose restrictions on the origins with which it can communicate once it inspects the sensitive data. Dually, it allows authors to share data via intermediate content while retaining its integrity.
Authors should be able to run code withleast privilege by restricting the origins the code can communicate with and thus how it can disseminate sensitive data.
Authors should be able toprivilege separate applications by compartmentalizing them into separate contexts that havedelegated privileges.
1.2.Use Cases/Examples
1.2.1.Confining untrusted third-party services
An author wishes to use a service, loaded in the form of an iframe, without trusting it (or its dependencies) to not leak her sensitive data. To protect the data, the author associates a confidentialitylabel with the data, specifying the origins allowed to read the data. The author then shares the newly createdlabeled object with the untrusted code. In turn, COWL confines the untrusted code once it inspects the sensitive data, as to ensure that it can only communicate according to the author-specified policy (the label).
https://example.com
wishes to use a third-party password strength checker provided byhttps://untrusted.com
. To protect the confidentiality of the password, thehttps://example.com
application can use COWL to associate a confidentiality policy, in the form of alabel, with the password before sending it to the untrusted service:// Create new policy usingLabels that specifies that the password is sensitive// to https://example.com and should only be disclosed to this origin:var policy = newLabel(window.location.origin);// Associate the label with the password:var labeledPassword = newLabeledObject(password, {confidentiality: policy});// Send the labeled password to the checker iframe:checker.postMessage(labeledPassword, "https://untrusted.com");// Register listener to receive a response from checker, etc.
Once the checker inspects theprotected object, i.e., the password, COWL limits the iframe to communicating with origins that preserve the password’s confidentiality (in this case,https://example.com
). This policy is enforced mandatorily, even if thehttps://untrusted.com
iframe sends the password to yet another iframe.
Note, until the checker actually inspects the labeled password, it can freely communicate with any origins, e.g., withhttps://untrusted.com
. This is important since the checker may need to fetch resources (e.g., regular expressions) to check the password strength. This is also safe—the checker has not inspected the sensitive password, and thus need not be confined.
Other use cases in this category include password managers and encrypted document editors, for example, where an encryption/decryption layer and a storage layer are provided by distrusting, but not malicious, services. The academic paper on COWL describes these use cases in detail[COWL-OSDI].
1.2.2.Sharing data with third-party mashups
A server operator wishes to provide third-party mashups access to user data. In addition to using CORS response headers to restrict theorigins that can access the data[CORS], the operator wishes to restrict how the data is further disseminated by these origins. To do so, the operator sends a response header field namedSec-COWL
(described in§3.5.2 The Sec-COWL HTTP Response Header Field) whose value contains the sensitivity of the data in the form of a serialized confidentialitylabel. In turn, COWL enforces the label restrictions on the third-party code.
https://provider.com
uses a CORS response header to granthttps://mashup.com
access to a resource. The operator also sets a COWL header to specify that the resource is confidential tohttps://provider.com
and should not be disseminated arbitrarily:Access-Control-Allow-Origin: https://mashup.comSec-COWL:data-confidentiality [ ["https://provider.com"] ]
COWL only allows ahttps://mashup.com
context to read the sensitive response if the label restrictions of the response are respected, i.e., if the code can only communicate withhttps://provider.com
.
Note, COWL only allows the code to inspect the response if thecontext labels, which dictate the context’s ability to communicate, are more restricting than the labels of the response. A more permissive approach, which does not require the context give up its ability to communicate arbitrarily is to uselabeled JSON response. Themashup XHR example shows how authors can accomplish this.
1.2.3.Content isolation via privilege separation
A server operator wishes to isolate content (e.g., of different users) while serving it from a single physicalorigin. The operator can leverageprivileges to ensure that content of one part of the site has different authority from another and, importantly, does not have authority of the physical origin. Concretely, when serving content, the operator can set the content’scontext privilege to a weaker,delegated privilege. This ensures that the content are privilege separated.
https://university.edu
wished to isolate different parts of their site according to users. The server operator can weaken the privilege of a page when serving user content by providing a response header field namedSec-COWL
(see§3.5.2 The Sec-COWL HTTP Response Header Field) whose value contains a serializeddelegated privilege. For example, for any content underhttps://university.edu/~user1
, the following header is set:Sec-COWL:ctx-privilege [ ['self', 'cowl://user1'] ]
Having this privilege can be understood as having the authority ofuser1
’s part of thehttps://university.edu
origin. COWL ensures that the content of this user cannot interfere with the content ofhttps://university.edu
or another user e.g.,user2
. For example, the content cannot modifyhttps://university.edu
cookies or the DOM of anotherhttp://university.edu
page.
Thisdelegated privilege also ensures that the content cannot disseminate data sensitive to another user (e.g.,user2
) arbitrarily— without being confined, it can only disseminateuser1
’s data onhttp://university.edu
. Of course, this requires the server operator to label sensitive data (e.g., when sending it to the user agent) appropriately (e.g.,user2
’s data is labeledLabel("https://university.edu")._or("user2")
).
Thesub-origin isolation in JavaScript example shows how this can be implemented using the COWL JavaScript APIs.
1.2.4.Running content with least-privileges
An author wishes to use a library that is tightly coupled with the page (e.g., jQuery), but not trust it to protect the user’s confidentiality and integrity. With COWL, the author can do this by loading the untrusted library afterdropping privileges (from the context’sdefault privilege). In doing so, the content (and thus the library) loses its implicit authority over the content’s origin.
https://example.com
can drop privileges in #"dfn" href="#context-privilege">context privilege to anempty privilege:COWL.privilege = newPrivilege();// Load untrusted libraryOr, by setting the content’s initial privilege to theempty privilege usingSec-COWL
response header:
Sec-COWL:ctx-privilege [ [] ]
In some cases it is useful for a particular context to have the privilege to disseminate certain categories of data. (Theor
part oflabels can be used to easily categorize differently-sensitive data.) To this end, the author should run the context with adelegated privilege instead of theempty privilege. The above§1.2.3 Content isolation via privilege separation shows one such example.
1.3.Trust Model
COWL provides developers with a way of imposing restrictions on how untrusted code can disseminate sensitive data. However, authors should avoid sharing sensitive data with malicious code, since such code may be able to exploit covert channels, which are present in most browsers, to leak the data. COWL can only prevent information leakage from code that (e.g., is buggy and) uses overt communication channels.Similarly, COWL provides no guarantees against attacks wherein users are manipulated into leaking sensitive data via out-of-band channels. For example, an attacker may be able to convince a user to navigate their user agent to an attacker-owned origin by entering a URL that contains sensitive information into the user agent’s address bar.
sandbox
.2.Key Concepts and Terminology
2.1.Labels
Anorigin label, or more succinctly alabel, encodes either a confidentiality or integrity security policy as conjunctive normal form (AND’s and OR’s) formulae overorigins. Labels can be associated withcontexts or withstructurally clonable objects.
When associated with acontext, the label restricts the origins that the context can communicate with, as detailed in§3.3 Labeled Contexts.
The confidentiality labelLabel("https://a.com")._or("https://b.com")
, when associated with a context, restricts the context to sending data tohttps://a.com
orhttps://b.com
, but no other origins. This context label reflects the fact the context may contain data that is sensitive to eitherhttps://a.com
orhttps://b.com
; it is thus only safe for it to communicateto these origins.Note, because the context can communicate data to either origin, another context associated with the more restricting label
Label("https://a.com")
cannot send it data. Doing so would allow for data confidential tohttps://a.com
to be leaked tohttps://b.com
.The integrity labelLabel("https://a.com").or("https://b.com")
, when associated with a context, restricts the context to receiving data from (a context or server) that is at least as trustworthy ashttps://a.com
orhttps://b.com
. This context label ensures that the code running in the context can only be influenced by data which eitherhttps://a.com
orhttps://b.com
endorse.When associated with an object, a confidentiality label specifies the origins to whom the object is sensitive, while an integrity label specifies the origins that endorse the object. Objects that have labels associated with them are calledlabeled objects.§3.4 Labeled Objects defines how labels are associated with objects.
Consider anhttps://example.com
page that receives a labeled object (e.g., viapostMessage()) with the following labels:Confidentiality:
Label("https://example.com")
.This label indicates that the object is sensitive tohttps://example.com
.Integrity:
Label("https://a.com")
. Thislabel indicates that the object has been endorsed byhttps://a.com
. Ifhttps://example.com
received the message from anintermediaryhttps://b.com
context, this labelreflects the fact that the object (produced byhttps://a.com
) was not tampered.
Mathematically, a label is aconjunctive normal form formula over origins[DCLabels].
A label is innormal form if reducing it according to thelabel normal form reduction algorithm produces the same value.
Two labels areequivalent if theirnormal form values are mathematically equal.
A labelAsubsumes (or is morerestricting than) another labelB if the result of running thelabel subsumption algorithm on thenormal forms ofA andB returns
true
. Labels are partially ordered according to this subsumes relation.Thecurrent confidentiality label is the confidentiality label associated with the current context.§3.3 Labeled Contexts specifies how labels are associated with contexts.
Thecurrent integrity label is the integrity label associated with the current context.§3.3 Labeled Contexts specifies how labels are associated with contexts.
When reading alabeled object, a context getstainted, i.e., itscontext labels are updated by invokingcontext tainting algorithm, to reflect that it has read sensitive (of potentially different trustworthiness) data and should be confined accordingly.
2.2.Privileges
Aprivilege is an unforgeable object that corresponds to alabel. Privileges are associated with contexts and reflect their authority.
Privileges can be used to bypass confinement restrictions imposed by confidentiality labels. In particular, a privilege can be used to bypass the restrictions imposed by any label its corresponding label—theinternal privilege label—subsumes.
Consider a context fromhttps://a.com
whosecurrent confidentiality label isLabel("https://a.com").and("https://b.com")
. This label confines the context to only communicating with entities whose labels are at least as restricting as this label. For example, it restricts the context from communicating with a context labeledLabel("https://b.com")
, since doing so could leakhttps://a.com
data tohttps://b.com
. It similarly prevents the context from communicating withhttps://a.com
.But, suppose that the context’scurrent privilege corresponds to
Label("https://a.com")
(afterall, the context originated fromhttps://a.com
). Then, the context would be able to bypass some of the restrictions imposed by the context label. Specifically, the context would be able to communicate withhttps://b.com
; the privilege confers it the right to declassifyhttps://a.com
data tohttps://b.com
. Indeed, when taking this privilege into consideration, theeffective confidentiality label of the context isLabel("https://b.com")
.Note, the privilege does not allow the context to bypass any label restrictions. For example, it does not allow the context to communicate with
https://a.com
since doing so could leakhttps://b.com
data.To be flexible, COWL uses the context privilege to remove certain restrictions imposed by thecontext label. To avoid accidentally leaking sensitive context data, authors should useLabeledObjects.Privileges can also be used to bypass integrity restrictions imposed by integrity labels. In particular, a privilege can be used to endorse an otherwise untrustworthy labeledcontext (orlabeled object) as to allow it to communicate with more trustworthy end-points (another context or server).
Consider anhttps://a.com
context whosecurrent integrity label isLabel("https://a.com")._or("https://b.com")
. This label confines the context to only communicating with entities that are at most as trustworthy as this label. For example, it restricts the context from communicating with a context whosecurrent integrity label isLabel("https://a.com")
, since doing so would potentially corrupthttps://a.com
data (e.g., by allowinghttps://b.com
to influence the computation).But, if the context’scurrent privilege corresponds to
Label("https://a.com")
, the context would be able to bypass some of these integrity restrictions. Specifically, the context would be able to communicate with the more-trustworthy context (labeledLabel("https://a.com")
) since the privilege confers it the right to endorse (or vouch for) its context on behalf ofhttps://a.com
. Indeed, when taking privileges into account, theeffective integrity label of the context isLabel("https://a.com")
.Note, the privilege cannot be used to bypass any integrity restrictions. For example, it does not allow the context to communicate with a context whose integrity label is
Label(https://b.com)
.Note,browsing contexts have acurrent privilege that, by default, corresponds to the origin of the context, as described in§3.3 Labeled Contexts. But, authors should set thecurrent privilege to adelegated privilege to follow the principle of least privilege.
Thecurrent privilege is the privilege associated with the current context.§3.3 Labeled Contexts specifies how privileges are associated with contexts.
Theeffective confidentiality label is the label returned by thelabel downgrade algorithm when invoked with thecurrent confidentiality label andcurrent privilege.
Theeffective integrity label is the label returned by thelabel upgrade algorithm when invoked with thecurrent integrity label andcurrent privilege.
Code can takeownership of aprivilegepriv by setting thecurrent privilege to the privilege produced via thecombination of thecurrent privilege andpriv. In doing so, it is said that the contextowns the privilege.
3.Framework
This sub-section is not normative.
In a nut-shell, the COWL framework provides:
- Policy specification viaorigin labels
- COWL provides aLabel interface for specifying confidentiality and integrity policies in terms oforigins.Labels can be associated with data and content using the JavaScriptLabeledObject andCOWL interfaces or the
Sec-COWL
HTTP headers. - Explicit authority viaprivileges
- The COWL framework provides a JavaScriptPrivilege interface for operating on and minting newprivileges. TheCOWL JavaScript interface and
Sec-COWL
HTTP response header can be used to explicitly control the authority of a context by setting thecontext privilege. - Confinement enforcement mechanism
- COWL extendsbrowsing contexts andWorkers with labels and privileges, which are used when enforcing confinement, i.e., when restricting a context’s network and cross-context messaging communication. This document defines the necessary changes and extensions to existing browser constructs and algorithms to enforce confinement.
3.1.Labels
Eachlabel is an immutable object represented by aLabel object, the interface of which is defined in this section.
ALabel MUST have an internallabel set, which is a non-empty set ofdisjunction sets.
Adisjunction set is a set oforiginURLs.
A label is said to be anempty label if itslabel set contains a single, emptydisjunction set.
[Constructor,Constructor(DOMStringorigin), Exposed=Window, Worker]interfaceLabel { booleanequals(Labelother); booleansubsumes(Labelother, optionalPrivilegepriv);Labeland((Label or DOMString)other);Label_or((Label or DOMString)other); objecttoJSON(); [Throws] staticLabelfromJSON(objectobj, optional DOMStringself);};
Current WebIDL implementation requires an underscore for certain identifiers. Can we rename_or
toor
?
3.1.1.Constructors
- Label()
- When invoking theLabel() constructor, the user agent MUST return a newempty label.
- Label(DOMString origin)
- When invoking theLabel(origin) constructor, the user agent MUST use an algorithm equivalent to the following:
If theorigin argument is not aURL, the constructor MUST throw a
TypeError
exception[ECMA-262] and terminate this algorithm.Else, it MUST return a newLabel that contains alabel set of a singledisjunction set, which itself MUST contain theURL corresponding to theorigin of the parameter.
3.1.2.Methods
- equals(Label other)
- The user agent MUST return
true
if theLabel on which the method has been called isequivalent to theother parameter; otherwise it MUST returnfalse
. - subsumes(Label other, optional Privilege priv)
- The user agent MUST use an algorithm equivalent to the following:
- and((Label or DOMString) other)
- The user agent MUST use an algorithm equivalent to the following:
LetO be theother argument.
If the type ofother is
DOMString
, run the following sub-steps:SetO to the result of invoking theLabel(other) constructor withother as an argument, if the constructor did not raise an exception.
Else, re-throw the exception and terminate this algorithm.
Return a newnormal formLabel that isequivalent to a label whoselabel set contains thedisjunction sets ofO and theLabel on which the method was invoked.
- _or((Label or DOMString) other)
- The user agent MUST use an algorithm equivalent to the following:
LetO be theother argument.
If the type ofother is
DOMString
, run the following sub-steps:SetO to the result of invoking theLabel(other) constructor withother as an argument, if the constructor did not raise an exception.
Else, re-throw the exception and terminate this algorithm.
Return a newLabel, innormal form, which isequivalent to adding each element of eachdisjunction set ofO’slabel set to eachdisjunction set of thelabel set of theLabel on which the method was called.
- toJSON()
- The user agent MUST use an algorithm equivalent to the following:
LetJSON lset be a newJSON array.
For eachdisjunction setdset in thelabel set of thelabel, this method was invoked on:
LetJSON dset be a JSON array of strings, each corresponding to an origin indset.
AppendJSON dset to theJSON lset array.
ReturnJSON lset.
- fromJSON(obj, self)
- The user agent MUST use an algorithm equivalent to the following:
Ifobj is not aJSON array of entries, each of which is aJSON array of strings, throw a
TypeError
exception[ECMA-262] and terminate this algorithm.Letself be null.
If theself argument is provided:
If the argument is not aURL, the function MUST throw a
TypeError
exception[ECMA-262] and terminate this algorithm.Else, setself to theself argument.
Letlab be a newempty label.
For each array elementdset ofobj:
Letdset label be a new empty label.
For each stringstr ofdset:
Ifstr is
"unique"
, letorigin be aglobally unique identifier.Much likeFreshPrivilege(),"unique"
is used to create a label component that is globally unique.Else, ifstr is
"self"
andself is not null, letorigin beself.Else, ifstr is aURL, letorigin bestr.
Else, throw a
TypeError
exception[ECMA-262] and terminate this algorithm.Letdset label be
dset label._or(origin)
Letlab be
lab.and(dset label)
3.1.3.Examples
// C: Public data.// I: Non-endorsed/untrustworthy data.var empty = newLabel();// C: Data confidential to a.com.// I: Data endorsed/trusted by a.com.var a = newLabel("https://a.com");// C: Data confidential to b.com.// I: Data endorsed/trusted by b.com.var a = newLabel("https://b.com");// C: Data confidential to both a.com and b.com// I: Data endorsed/trusted by a.com and b.com.var aANDb = newLabel("https://a.com").and("https://b.com");// C: Data confidential to either a.com or b.com.// I: Data endorsed/trusted by either a.com or b.com.var aORb = newLabel("https://a.com")._or("https://b.com");
Examples of label comparisons with intuition for the semantics.
// C: Data confidential to a.com (b.com) data is more sensitive than public data.// I: Data endorsed by a.com (b.com) is more trustworthy than non-endorsed/untrustworthy data.a.subsumes(empty) === true;b.subsumes(empty) === true;// C: Data that is confidential to a.com and b.com is more// confidential than data that is only sensitive to a.com (b.com).// I: Data that is endorsed/trusted by both a.com and b.com is// more trustworthy than data endorsed only by a.com (b.com).aANDb.subsumes(a) === true;aANDb.subsumes(b) === true;// C: Data that that is confidential to a.com (b.com) is not comparable to// data that is confidential to b.com (a.com).// I: Data that that is endorsed by a.com (b.com) is not comparable to// data that is endorsed by b.com (a.com).a.subsumes(b) === false;b.subsumes(a) === false;// C: Data that is confidential to a.com (b.com) is more confidential than data that is// confidential to either a.com or b.com. Alternative intuition: data that can be read by// a.com or b.com can be read by an entity that can read a.com (b.com) data alone.// I: Data that is endorsed by a.com (b.com) is more trustworthy than data that is endorsed// by either a.com or b.com. Alternative intuition: an entity that trusts data endorsed// by either a.com or b.com necessarily trusts data endorsed by a.com (b.com) alone.a.subsumes(aOrb) === true;b.subsumes(aOrb) === true;
var aORbANDc = aORb.and(newLabel("https://c.com");
Converting to JSON:
JSON.stringify(empty) === '[[]]';JSON.stringify(a) === '[["https://a.com"]]';JSON.stringify(aANDb) === '[["https://a.com"], ["https://b.com"]]';JSON.stringify(aORb) === '[["https://a.com", "https://b.com"]]';JSON.stringify(aORbANDc) === '[["https://a.com", "https://b.com"], ["https://c.com"]]';
Converting from JSON:
Label.fromJSON([[]]).equals(empty) === true;Label.fromJSON([["https://a.com"]]).equals(a) === true;Label.fromJSON([["https://a.com"], ["https://b.com"]]).equals(aANDb) === true;Label.fromJSON([["https://a.com", "https://b.com"]]).equals(aORb) === true;Label.fromJSON([["https://a.com", "https://b.com"], ["https://c.com"]]).equals(aORbANDc) === true;Label.fromJSON([["self"]], "https://a.com").equals(a) === true;Label.fromJSON([["unique"]]).equals(Label.fromJSON([["unique"]])) === false;
3.2.Privileges
Eachprivilege is an immutable object represented by aPrivilege object, the interface of which is defined in this section.
APrivilege MUST have aninternal privilege label.
Thecombination of privilegesA andB is a privilege produced by invoking thecombine() method onA (respectively,B) withB (respectively,A) as an argument.
A privilege is said to be anempty privilege if itsinternal privilege label is theempty label. A context is said to beunprivileged if its context privilege is theempty privilege. By setting thecontext privilege to theempty privilege, a context is said to bedropping privileges.
A privilegeP1 is said to be adelegated privilege ofP2 ifP2’sinternal privilege labelsubsumesP1’sinternal privilege label.
[Constructor, Exposed=Window, Worker]interfacePrivilege { staticPrivilegeFreshPrivilege(); // Named constructorLabelasLabel();Privilegecombine(Privilegeother); [Throws]Privilegedelegate(Labellabel);};
Bikeshed does not allow WebIDL’s NamedConstructor. For now, inlining the constructor as a static method.
3.2.1.Constructors
- Privilege()
- When invoking thePrivilege() constructor, the user agent MUST return a newPrivilege that has aninternal privilege label set to
Label()
. - FreshPrivilege()
When invoking theFreshPrivilege() constructor, the user agent MUST use an algorithm equivalent to the following:
Letunique Label be the label produced by invoking theLabel(other) constructor with aglobally unique identifier.
Return a newPrivilege that has aninternal privilege label set tounique Label.
3.2.2.Methods
- asLabel()
- The user agent MUST return theinternal privilege label of thePrivilege on which the method has been called.
- combine(Privilege other)
The user agent MUST return a newPrivilege whoseinternal privilege label isequivalent to alabel created according to an algorithm equivalent to the following:
LetinternalLabel be theinternal privilege label of thePrivilege on which the method has been called.
LetotherLabel be theinternal privilege label of theother argument.
Return
internalLabel.and(otherLabel)
.
- delegate(Label label)
The user agent MUST return a newPrivilege whoseinternal privilege label isequivalent to alabel created according to an algorithm equivalent to the following:
LetinternalLabel be theinternal privilege label of thePrivilege on which the method has been called.
If theinternalLabel does notsubsume thelabel argument, throw a
SecurityError
exception and terminate this algorithm.Else, return a newPrivilege that has aninternal privilege label set tolabel.
3.2.3.Examples
https://example.com
has a privilege whoseinternal privilege label isLabel("https://example.com")
.As a result, reading data that is sensitive toLabel("https://example.com")
does not confine the context. For example, reading alabeled object whose confidentiality label isLabel("https://example.com")
does not restrict the context from communicating—and thus accidentally leaking that object’s contents—to another origin. To prevent accidental leaks, the author should drop privileges by setting thecurrent privilege to anempty privilege:
// Save privilege in case we need it later:var __savedPriv = COWL.privilege;// Drop privilege (set thecontext privilege to theempty privilege):COWL.privilege = newPrivilege();
After this point, if the context reads data with aLabel("https://example.com")
confidentiality label, COWL will restrict it to communicating withhttps://example.com
.
// Create new fresh privilege:var priv = newFreshPrivilege();// Takeownership of the fresh privilege:COWL.privilege = COWL.privilege.combine(priv);// Associate the unique label with the password:var labeledPassword = newLabeledObject(password, {confidentiality: priv.asLabel()});// Send the labeled password to the checker iframe:checker.postMessage(labeledPassword, "https://untrusted.com");
Once thehttps://untrusted.com
context reads the password it will betainted by the unique,internal privilege label ofpriv
; the unique origin ensures that it cannot send the password to, for example, public parts ofhttps://example.com
. Indeed, only the owner ofpriv
can disseminate the labeled password (result) arbitrarily.
https://university.edu
isolates different parts of their site according to users. Foruser1
it can do this as follows:// Create a label corresponding to the university origin:var uni = newLabel(window.location.origin);// Create a new label that corresponds to user1’s data on university.edu:var user1 = uni._or("cowl://user1"); // Here the cowl:// is an arbitraryscheme// Originally, COWL.privilege.asLabel().equals(uni).// Drop the currentcontext privilege to a delegated privilege:COWL.privilege = COWL.privilege.delegate(user1);
At this point, the context can only arbitrarily disseminate data that is labeledLabel("https://university.edu")._or("cowl://user1")
; it cannot disseminate data that is sensitive to the university (e.g., which is labeledLabel("https://university.edu")
) or to another user (e.g.,user2
’s data is labeledLabel("https://university.edu")._or("cowl://user2")
).
3.3.Labeled Contexts
COWL extendsbrowsing contexts andWorkers with aCOWL state, which is used to restrict the context’s communication channels. In this document, the termcontext is used to refer to bothbrowsing contexts andWorkers. The COWL state consists of:
Theconfinement mode status, which indicates whetheror not COWL confinement is enabled and thuslabels shouldbe enforced in the current context.
Thecontextlabels, which consist of:
Thecontextprivilege, which encodes the context’sability to bypass the restrictions of certain labels.
Each context’sCOWL state MUST be initially set to thedefault COWL state, where:
Theconfinement mode is disabled.
Thecontext confidentiality label is set to thedefault confidentiality label:empty label.
Thecontext integrity label is set to thedefault integrity label:empty label.
Thecontext privilege is set to thedefault privilege: aprivilege whoseinternal privilege label isequivalent toLabel(origin), whereorigin is the string representation of the context orWorker’sorigin.
Unlessconfinement mode is enabled, a context is notsubject to confinement.
Unless thecurrent confidentiality label and thecurrent integrity label arenon-empty labels, the context’s communicationis unrestricted; code is onlysubject to the restrictions imposed by other mechanisms such asthe Same-Origin Policy and CSP.
Unless thecurrent privilege is dropped or set to adelegated privilege, code can disseminate data sensitiveto the browsing context’sorigin, even whenconfinementmode is enabled. Such data is implicitlydeclassified using thecontext privilege. Authors should sendLabeledObjects to explicitly communicate thesensitivity (and integrity) of the data they are sharing.
Each context’sCOWL state is made available via theCOWL interface defined below.
[Exposed=Window, Worker]interfaceCOWL { static voidenable(); static booleanisEnabled(); [SetterThrows] static attributeLabelconfidentiality; [SetterThrows] static attributeLabelintegrity; [SetterThrows] static attributePrivilegeprivilege;};
3.3.1.Attributes
- confidentiality, of typeLabel
On getting, the user agent MUST return thecurrentconfidentiality label.
On setting, the user agent MUST use an algorithm equivalentto the following:
Enableconfinement mode.
Letconf be the set confidentiality label.
LetcanWrite be the result of invoking thewrite check algorithm withconf and thecurrent integrity label.
IfcanWrite is
false
, throw aSecurityError
exception and terminate this algorithm.Else, set thecurrent confidentiality label toconf.
- integrity, of typeLabel
On getting, the user agent MUST return thecurrentintegrity label.
On setting, the user agent MUST use an algorithm equivalentto the following:
Enableconfinement mode.
Letint be the set integrity label.
LetcanWrite be the result of invoking thewrite check algorithm with thecurrent confidentiality label andint.
IfcanWrite is
false
, throw aSecurityError
exception and terminate this algorithm.Else, set thecurrent integrity label toint.
- privilege, of typePrivilege
On getting, the user agent MUST return thecurrentprivilege.
On setting, the user agent MUST enableconfinement mode and set thecurrent privilege to the set privilege.
3.3.2.Methods
- enable()
- On invocation, the user agent MUST enableconfinement mode by setting the current context’sCOWL state confinement mode status.
- isEnabled()
- On invocation, the user agent MUST return
true
if theconfinement mode is enabled for the current context; else, it MUST returnfalse
3.3.3.Examples
Below are several examples showing how to use theCOWL API. The§3.2.3 Examples illustrate the use ofcontext privileges.COWL.isEnabled() === false;COWL.enable();COWL.isEnabled() === true;
At this point, no confinement restrictions are applied—COWL is backwards compatible with the existing model. But, the context labels can be set to restrict communication.
COWL.integrity = newLabel(window.location.origin);
https://mashup.com
can set thecontext confidentiality label to receive data sensitive fromhttps://provider.com
:COWL.confidentiality = newLabel('https://provider.com');
At this point, the context can only communicate withhttps://provider.com
. The data provider can ensure that only appropriately labeled contexts can inspect an HTTP response by setting response labels using theSec-COWL
response header.
3.4.Labeled Objects
ALabeledObject interface represents an immutable object that is protected by a confidentiality and integrity label, i.e., the object has associated labels.
This API is designed to be used in conjunction with other APIs and elements on the web platform. In particular,postMessage(),Web Workers, andXMLHttpRequest (e.g., with an overloadedsend()
method forLabeledObject arguments).
ALabeledObject MUST have an internalprotected object, a confidentialitylabel, and an integritylabel. The interface is defined below.
dictionaryCILabel {Label?confidentiality;Label?integrity;};[Constructor(objectobj,CILabellabels), Exposed=Window, Worker]interfaceLabeledObject { readonly attributeLabelconfidentiality; readonly attributeLabelintegrity; [GetterThrows] readonly attribute objectprotectedObject; [Throws]LabeledObjectclone(CILabellabels);};
3.4.1.Constructors
- LabeledObject(obj, labels)
When invoking theLabeledObject() constructor, the user agent MUST use an algorithm equivalent to the following:
Letobj clone be the result of obtaining astructured clone of theobj argument.
Letconf be theconfidentiality member of thelabels argument, if it is set. Otherwise, letconf be thecurrent confidentiality label.
Letint be theintegrity member of thelabels parameter, if it is set. Otherwise, letint be thecurrent integrity label.
LetcanWrite be the result of invoking thewrite check algorithm with theconf andint labels.
IfcanWrite is
false
, the constructor MUST throw aSecurityError
exception and terminate this algorithm.Else, the user agent MUST return a newLabeledObject, with theprotected object set toobj clone, the confidentiality label set toconf, and the integrity label set toint.
3.4.2.Attributes
- confidentiality, of typeLabel, readonly
- On getting, the user agent MUST return theLabeledObject’s confidentiality label.
- integrity, of typeLabel, readonly
- On getting, the user agent MUST return theLabeledObject’s integrity label.
- protectedObject, of typeobject, readonly
On getting, the user agent MUST use an algorithm equivalent to the following:
Invoke thecontext tainting algorithm with theLabeledObject’s confidentiality and integrity labels.
ReturnLabeledObject’sprotected object.
The context can’t violate the confidentiality of the data (asspecified by the confidentiality label) by communicatingarbitrarily once it reads data labeled as such.
The context can’t violate the integrity of entities moretrustworthy than the data. (The trustworthiness of the data isspecified by the integrity label.) In particular, once thecontext reads the data and getstainted, the rest of thecomputation is restricted to writing to entities that are atmost as trustworthy as the data, since the read data may haveinfluenced the computation.
3.4.3.Methods
- clone(CILabel labels)
On invocation, the user agent MUST use an algorithm equivalent to the following:
Letobj be theprotected object of the object on which the method was invoked.
Letconf be the confidentiality label of the object on which the method was invoked.
Letint be the integrity label of the object on which the method was invoked.
LetnewConf be theconfidentiality member of thelabels argument, if it is set. Otherwise, letnewConf beconf.
LetnewInt be theintegrity member of thelabels parameter, if it is set. Otherwise, letnewInt beint.
Letprivs be theinternal privilege label of the currentcontext privileges.
If
newConf.subsumes(conf,privs)
returnsfalse
or ifint.subsumes(newInt,privs)
returnsfalse
, the method MUST throw aSecurityError
exception and terminate this algorithm.Note, these checks ensure that the new labels of the object are at least as restricting as the original labels, taking into consideration the privileges of the context.
Else, return a newLabeledObject, with theprotected object set toobj, the confidentiality label set tonewConf, and the integrity label set tonewInt.
3.4.4.Examples
Below are several examples showing the usage ofLabeledObjects.§1.2.1 Confining untrusted third-party services gives an example of howLabeledObjects can be used to confine third-party libraries (e.g., a password strength checker).§3.6.1.1 Examples and§3.6.2.1 Examples show howLabeledObjects are used with theXMLHttpRequest constructor.https://police.gov
wishes to plot the location of police cars on a map provided byhttps://maps.biz
without revealing the individual car locations. After revealing the general area tohttps://maps.biz
, the author ofhttps://police.gov
labels the police car coordinates and sends them to the mapping service:// Fetch map for provided location and draw itmapsIframe.postMessage({ cmd: 'draw', location: ... }, mapsOrigin);var locations = ... // Array of police-car coordinates// Label the locations:var labeledLocations = newLabeledObject(locations, { confidentiality: newLabel(window.location.origin) });// Send the labeled locations and plot themmapsIframe.postMessage({ cmd: 'plot', locations: labeledLocations }, mapsOrigin);
When receiving adraw
message, the author ofhttps://maps.biz
navigates the iframe map (a nested context) to draw the map; otherwise, it simply forwards messages from the parent (e.g.,plot
,zoom
, andmove
). (This design ensures that only the innermost iframe gets tainted.)
The innermost map iframe registers a handler, that, for example, draws cars on top of map tiles:
window.addEventListener("message", function (event) { switch (event.data.cmd) { case 'plot': var coordinates = event.data.locations.protectedObject; coordinates.forEach(function (coordinate) { // add car to map at coordinate }); case 'zoom': ... case 'move': ... ... };}, false);
Note that before getting the firstprotectedObject, the iframe can communicate arbitrarily, e.g., to fetch map tiles. But once it inspects the confidential locations COWL confines the code—it restricts it to only communicating withhttps://police.gov
. Importantly, it can keep receiving messages from its parent context viapostMessage() to, for instance, move a car.
https://example.com
wishes to ensure that a particular JSON object conforms to a set of validation filters before submitting it to a remote server. (Consider, for example, a form validator that checks if an email address is valid.) To this end, it labels the JSON and sends thelabeled object to (e.g., a Worker or iframe) that performs the validation.The validation author inspects the object, but only endorses it if it conforms to the spec:
function handler(lObj) { if (validateA(lObj.protectedObject)) { var origin = ... ; // current origin (e.g., window.location.origin) var endorsement = newLabel(origin)._or('cowl://validate-A'); // Return a clone of the labeled object that is additionally // endorsed by the current (sub-)origin. return lObj.clone({ integrity: lObj.integrity.and(endorsement) }); } else { return null; }}
The author ofhttps://example.com
can then pass the endorsed object to other validators or end-point (e.g., a server), who can, in turn, further endorse the object or verify the origins that have endorsed it.
3.5.TheSec-COWL
HTTP Headers
TheSec-COWL
HTTP request and response headers are used by user agents and servers to conveylabel metadata to servers and user agents, respectively.
Label metadata is eitherlabeled context metadata orlabeled data metadata.
Labeled context metadata encodesCOWL state information, including:
the serializedcontext confidentiality label given by thectx-confidentiality directive,
the serializedcontext integrity label given by thectx-integrity directive, and
the serializedcontext privilege’sinternal privilege label given by thectx-privilege directive.
Its ABNF is:
ctx-metadata =ctx-directive *( ";" [ctx-directive ] )ctx-directive = *WSPctx-directive-name 1*WSPlabel-setctx-directive-name = "ctx-confidentiality" / "ctx-integrity" / "ctx-privilege"
Labeled data metadata is used to convey the confidentiality and integrity labels of an HTTP request or response, using thedata-confidentiality anddata-integrity directives. Its ABNF is:
data-metadata =data-directive *( ";" [data-directive ] )data-directive = *WSPdata-directive-name 1*WSPlabel-setdata-directive-name = "data-confidentiality" / "data-integrity"
The ABNF forserialized labels is:
label-set = "["disjunction-set *( "," [disjunction-set ] ) "]" /empty-labeldisjunction-set = "[" [source-expression *( "," [source-expression ] ) ] "]"source-expression = "'self'" /host-sourceempty-label = "[" *WSP "[" *WSP "]" *WSP "]"
The parsing algorithms forlabel metadata are given in§4.10 Parse labeled data metadata and§4.11 Parse labeled context metadata.
3.5.1.TheSec-COWL
HTTP Request Header Field
The ABNF for theSec-COWL
HTTP request header is:
"Sec-COWL:" (ctx-metadata [ ","data-metadata ] ) / (data-metadata [ ","ctx-metadata ] )
The user agent MUST send a header field namedSec-COWL
along with requests ifconfinement mode is enabled. The value of this header MUST contain thelabeled context metadata of the context that performed the request. Thislabeled context metadata MUST include the currentcontext confidentiality label,context integrity label, andcontext privileges. The user agent MAY send another header with this field name whose value islabeled data metadata (e.g., when sendinglabeled objects withXMLHttpRequest).
Note, according to[RFC2616], the user agent MAY combine multiple header field values into a single, comma-separated value.
http://a.com
page that has read data sensitive tohttp://b.com
.Sec-COWL:ctx-confidentiality [ ['https://b.com'] ];ctx-integrity [ [] ];ctx-privilege [ ['https://a.com'] ];
http://university.edu
context thatowns adelegated privilege and aFreshPrivilege().Sec-COWL:ctx-confidentiality [ [] ];ctx-integrity [ [] ];ctx-privilege [ ['http://university.edu', 'cowl://user1'], ['cowl://a0281e1f-8412-4068-a7ed-e3f234d7fd5a'] ];
When processing a request, a server SHOULD only use the firstSec-COWL
header that contains actx-metadata directive to retrive thelabeled context metadata. Similarly, a server SHOULD only use the firstSec-COWL
header that contains adata-metadata directive to retrive thelabeled data metadata of the request.
3.5.2.TheSec-COWL
HTTP Response Header Field
The ABNF for theSec-COWL
HTTP response header is:
"Sec-COWL:"ctx-metadata /data-metadata
The header value may containlabeled context metadata which can be used to set the initialCOWL state of a context; or it may containlabeled data metadata which specifies the sensitivity of the response (which COWL then uses to determine whether or not to block the response).
https://university.edu/~user1
page should run with a delegated privilege—namely,Label("https://university.edu/")._or("cowl://user1")
—from the start:Sec-COWL:ctx-privilege [ ['self', 'cowl://user1'] ];
http://a.com
may wish to respond to a request with data that is sensitive to bothhttps://a.com
andhttps://b.com
, while simultaneously indicating that it endorses the response data:Sec-COWL:data-confidentiality [ ['https://a.com'], ['https://b.com'] ];data-integrity [ ['https://a.com'] ];
COWL blocks the response unless the current context’s labels are at least as restricting.
To process this header, the user agent MUST use theProcessresponse torequest as COWL algorithm when performing afetch, as described in§3.7.1 Modifications to Fetch.
3.6.Extensions to XMLHttpRequest
The XMLHttpRequest specification SHOULD contain the modifications described below to enable the rest of this specification’s work[XHR].
3.6.1.Sendinglabeled objects
To allow authors to sendlabeled objects to a remote server, this specification extends theXMLHttpRequest interface with an overloadedsend()
method:partial interfaceXMLHttpRequest { voidsend(LabeledObjectlobj);};
Thesend(lobj) method MUST use an algorithm that is equivalent to the following:
Letobj be theprotected object of thelobj argument.
Letconf be the confidentiality label of thelobj argument.
Letint be the integrity label of thelobj argument.
Letprivs be the currentcontext privileges.
LetremoteConf be thelabel returned by theLabel(origin) constructor called with theurl associated with therequest.
If
responseConf.subsumes(conf,privs)
returnsfalse
, throw aSecurityError
and terminate this algorithm.The user agent SHOULD warn the user that the script attempted to leak data to a remote server.Letjson be a newJSON object with the following entries:
Set the
Content-Type
header to`application/labeled-json`
.Append a header named
Sec-COWL
to theauthor request headers associated with the object this methods was called on. The value of theSec-COWL
header MUST belabeled data metadata containing the confidentiality and integrity labels of thelobj argument.Invoke the
send()
method on the object this method was called on withjson as an argument.Note, that
send()
throws an exception in step 4 ifobj cannot beserialized. User agents MUST ensure that allprotected objects can be serialized at the time of creatingLabeledObjects.This algorithm does not check if the integrity label of the object subsumes the server’s integrity label. It is the server’s responsibility to ensure that untrustworthy data does not affect its computation in an unsafe way. Indeed, the only reason for checking the confidentiality labels is because the user agent has no way to ensure that the server will respect the confidentiality of the data.
3.6.1.1.Examples
https://example.com
sends JSON object endorsed byhttps://validator.com
:// Suppose that labeledObject is a public, high-integrity value:JSON.stringify(labeledObject.confidentiality) === '[[]]';JSON.stringify(labeledObject.integrity) === '[["https://validator.com"]]';// Create an XHR request:var req = new XMLHttpRequest()req.open("POST", "https://example.com/...");// Send the labeled object:req.send(labeledObject);
Assuming the context has adefault COWL state,send()
would send an HTTP request of the form:
Sec-COWL:ctx-confidentiality [[]];ctx-integrity [[]];ctx-privilege [["https://example.com"]];Sec-COWL:data-confidentiality [[]];data-integrity [["https://validator.com"]];Content-Type: application/labeled-json;{ "confidentiality": [[]], "integrity": [["https://validator.com"]], "object": ...}
The server can then verify the integrity label of the request and ensure that, if the user agent is conformant, the data was endorsed byhttps://validator.com
.
3.6.2.Receivinglabeled objects
To allow authors to receivelabeled objects from remote servers, the XMLHttpRequest specification SHOULD contain the following modifications[XHR]:The
XMLHttpRequestResponseType
enumeration is extended with a new response type:enumXMLHttpRequestResponseType { // ... existing response types ... "labeled-json"};
TheResponsebody section of the specification is modified to add:
AnXMLHttpRequest has associatedresponseLabeledObject object.
Alabeled JSON response is the return value of these steps:
If theresponse LabeledObject object is non-null, return it.
IfresponseType is not
"labeled-json"
or thefinal MIME type is notapplication/labeled-json
, return null.Ifbytes is null, return null.
LetJSON text be the result of runningutf-8 decode on byte streambytes.
LetJSON object be the result of invoking the initial value of the
parse
property of theJSON
object, withJSON text as its only argument. If that threw an exception, return null.[ECMA-262]If theJSON object is missing any of the three entries:
"object"
,"confidentiality"
, or"integrity"
return null.Letprotected object be the value of the
"object"
entry.Letconf be thelabel returned by calling thefromJSON() function with the
"confidentiality"
entry of theJSON object andself. If the function threw an exception, return null.Letint be thelabel returned by calling thefromJSON() function with the
"integrity"
entry of theJSON object andself. If the function threw an exception, return null.LetresponseInt be thelabel returned by theLabel(origin) constructor called withself.
IfresponseInt does not subsumeint, return null.
Should the user agent warn the user if the server provided an integrity label that it is not allowed to provide?
Set thelabeled JSON response to a newly createdLabeledObject whoseprotected object isprotected object, confidentiality label isconf, and integrity label isint.
Return thelabeled JSON response.
Modify theresponse attribute by adding the following clause to step 2 of the↪ Otherwise clause:
↪ IfresponseType is
"labeled-json"
Return thelabeled JSON response.
Modify step 12 of theopen() method by adding the following sub-step:
Setresponse LabeledObject object to null.
3.6.2.1.Examples
Specifically, the server operator ofhttps://provider.com
uses a CORS response header to sendhttps://mashup.com
a labeled JSON object. To ensure that the data is protected it sets theContent-Type
response header value to`application/labeled-json`
and sets the labels appropriately:
Access-Control-Allow-Origin: https://mashup.comContent-Type: application/labeled-json;{ "confidentiality": [[]], "integrity": [["https://provider.com"]], "object": ...}
The confidentiality label specifies that the object is confidential tohttps://provider.com
and should not be disseminated arbitrarily.
The author ofhttps://mashup.com
can read such labeled responses by simply setting theresponseType accordingly:
// Create an XHR request to get the data:var req = new XMLHttpRequest()req.open("GET", "https://provider.com/apis/...");req.responseType = "labeled-json";req.onload = function (e) { var labeledObject = req.response; // is aLabeledObject // At this point, the context is still untainted, but: JSON.stringify(labeledObject.confidentiality) === '[[]]'; JSON.stringify(labeledObject.integrity) === '[["https://provider.com"]]';};req.send();
Here, COWL sets theresponse to a newLabeledObject, but does nottaint the context with the response label. Indeed thehttps://mashup.com
integrator can perform many other requests to different origins. Only when theprotected objects of theselabeled objects are used will COWL taint the context and impose the label restrictions.
Access-Control-Allow-Origin: *Content-Type: application/labeled-json;{ "confidentiality": [["'unique'"]], "integrity": [[]], "object": ... base64-encoded image ...}
Once the receiver inspects theprotectedObject of the response, COWLtaints the context and ensures that it cannot communicate with anybody.
3.7.Confinement Enforcement
This sub-section is non-normative
To enforce confinement, COWL ensures that code in acontext cannot send data (e.g., viacross-document messaging or by performing afetch) to contexts or servers that do not preserve the confidentiality of the data. Similarly, COWL ensures that a context cannot receive data from a context or server that is less trustworthy.
3.7.1.Modifications to Fetch
The Fetch specification SHOULD contain the following modifications in order to enable the rest of this specification’s work[FETCH]:
Perform the following step between step 4 and 5 in the "main fetch" algorithm:
Ifshould fetchingrequest be blocked as COWL returnsblocked, setresponse to anetwork error.
Perform the following step between step 12 and 13 in the "main fetch" algorithm:
Ifprocessresponse torequest as COWL returnsblocked, setresponse to anetwork error.
3.7.2.Modifications to Web Messaging
The Web Messaging specification SHOULD contain the following modifications in order to enable the rest of this specification’s work[WEBMESSAGING]:
Perform the following step between step 9 and 10 in theposting messages algorithm:
Letconf be the current context’seffective confidentiality label.
Letint be the current context’seffective integrity label.
LetdstState be theCOWL state associated with the
Document
of theWindow
object on which the method was invoked.Ifconfinement mode fordstState is enabled, letdstConf be thedstStateeffective confidentiality label.
Else, letdstConf be theLabel returned by thelabel upgrade algorithm when invoked with thedstStatecontext confidentiality label andcontext privilege.
Note, if the receiver has not enabledconfinement mode, COWL flexibly assumes that it can receive data sensitive to its origin (in using thelabel upgrade).
LetdstInt be thedstStateeffective integrity label.
IfdstConf does notsubsumeconf or ifint does notsubsumedstInt, then abort the remaining steps silently.
Perform the following step between step 9 and 10 in theMessagePort
postMessage()
method:Letconf be the current context’seffective confidentiality label.
Letint be the current context’seffective integrity label.
LetdstState be theCOWL state associated with theowner of thetarget port theMessage Port
postMessage()
was called on.Ifconfinement mode fordstState is enabled, letdstConf be thedstStateeffective confidentiality label.
Else, letdstConf be theLabel returned by thelabel upgrade algorithm when invoked with thedstStatecontext confidentiality label andcontext privilege.
Note, if the receiver has not enabledconfinement mode, COWL flexibly assumes that it can receive data sensitive to its origin (in using thelabel upgrade).
LetdstInt be thestateeffective integrity label.
IfdstConf does notsubsumeconf or ifint does notsubsumedstInt, then abort the remaining steps.
3.7.3.Modifications to HTML5
Whenconfinement mode is enabled the user agent MUST ensure that content cannot access other content from the same origin (e.g., using an iframe’scontentDocument
) that would violate label restrictions. Specifically, if abrowsing context’sconfinement mode is enabled the user agent MUST set the following flags of the context’sactive sandboxing flag set:
If the context’seffective confidentiality label or integrity label are not theempty label, the user agent MUST additionally set the following flags:
Thesandboxed origin browsing context flag. Thisflag ensures that the browsing context cannot access contentof (what was previously) the same origin. It also preventsscript from reading from or writing to the
document.cookie
IDL attribute, andblocks access tolocalStorage
.[WEBSTORAGE]The user agent MUST ensure that if content has access to another content from the same origin, but either ends up enablingconfinement mode and has a non-empty label, access must be revoked and the two must be considered as if they are of different origins. Th current version of this document specifies this requirement in terms of thesandboxed origin browsing context flag.Implementation-wise, this may pose a challenge for certain browsers. An alternative design may disallow enabling confinement mode if the browsing context has any references to or from another same-origin content. Feedback on this would be very welcome.
Should COWL restrict communication via less overt channels (e.g., height/width of an iframe, URL fragment, or even)index inwindow.top.frames
)? Maybe as optional modifications to HTML? Feedback on this would be very welcome.
4.Algorithms
4.1.Label Normal Form Reduction
Thelabel normal form reduction algorithm takes alabel argument and produces aLabel value according to the following steps:Letlset be thelabel set of anempty label.
For eachdisjunction setdset in thelabel set oflabel:
If there is nodisjunction set inlset that is a subset ofdset, then:
Remove everydisjunction set inlset thatdset is a subset of.
Adddset tolset.
Note, this algorithms assumes thatdisjunction sets andlabel sets do not have duplicate elements, much like mathematical sets.
var a =Label("https://a.com"); // https://a.comvar aORb =Label("https://a.com")._or("https://b.com"); // https://a.com OR https://b.comvar a2 = a.and(aORb); // https://a.com AND (https://a.com OR https://b.com) ≡ https://a.com
The labela2
is equivalent toa
(sincea.subsumes(aORb)
):
JSON.stringify(a2) === '[["https://a.com"]]';a2.equals(a);
4.2.Label Subsumption
Thelabel subsumption algorithm takes a two labelsA andB and produces a boolean according to these steps:If, for eachdisjunction setb in thelabel set ofB there isdisjunction seta in thelabel set ofA such thata is asubset ofb, return
true
.
Else, return
false
.
Note, when interpreting labels as mathematical formulae,label subsumption is logical implication:A subsumesB is equivalent asAimpliesB, i.e,A⇒B.
4.3.Label Downgrade
Thelabel downgrade algorithm takes a confidentiality labellabel and a privilegepriv, and returns the least restricting label according to the following steps:LetprivLabel be theinternal privilege label ofpriv.
Letlset be thelabel set of anempty label.
For eachdisjunction setdset in thelabel set oflabel:
Note,label downgrade removes every disjunction set permitted bypriv. This is used to safely declassify data labeledlabel.
4.4.Label Upgrade
Thelabel upgrade algorithm takes an integrity labellabel and a privilegepriv, and returns the most permissive label according to the following steps:LetprivLabel be theinternal privilege label ofpriv.
Return
label.and(privLabel)
.
Note,label upgrade is the dual oflabel downgrade. This can be used to safely endorse data labeledlabel (and thus potentially already endorsed).
4.5.Context Tainting
Thecontext tainting algorithm takes a two labels,confidentiality andintegrity, and updates thecontext labels to allow for reading data labeled with these labels. The user agent MUST use an algorithm whose behavior is as follows:LetcurrentConf be the currentcontext confidentiality label.
LetcurrentInt be the currentcontext integrity label.
Set thecontext confidentiality label to theLabel returned by the by thelabel downgrade algorithm when invoked withcurrentConf.and(confidentiality) andcurrent privilege.
Set thecontext integrity label to theLabel returned by the by thelabel downgrade algorithm when invoked withcurrentInt._or(integrity) andcurrent privilege.
4.6.Write Check
Thewrite check algorithm takes two labels,objConf andobjInt, and returnstrue
if the current context is allowed to write to (or create) an entity labeled as such; otherwise, it returnsfalse
. The user agent MUST use an algorithm whose behavior is as follows:LetcurrentConf be the current context’seffective confidentiality label.
LetcurrentInt be the current context’seffective integrity label.
IfobjConf does notsubsumecurrentConf or ifcurrentInt does notsubsumesobjInt, return
false
.Else, return
true
.
4.7.Structured Cloning
When a user agent is required to obtain astructured clone of an object whose type is defined in this document, it MUST use an algorithm whose behavior is as follows:Letinput be the value being cloned.
Ifinput is aLabel object, letoutput be a newly constructedLabel object with the samelabel set as that ofinput.
Ifinput is aPrivilege object that was constructed with theFreshPrivilege() constructor, letoutput be a newly constructedPrivilege object with the sameinternal privilege label as that ofinput.
To prevent attacks that launder page privileges, the current version of COWL only allows transferring fresh privileges.We can be more permissive and allow transferring all butdefault privileges. Feedback on this would be welcome.
Ifinput is aLabeledObject object, letoutput be a newly constructedLabeledObject object with the same internalprotected object, confidentiality label, and integrity label as that ofinput.
Returnoutput.
Note, cross-context messaging constructs such aspostMessage() use thestructured clone algorithm (e.g., see theinternal structured cloning algorithm). This algorithm is used to allow authors to transfer COWL object, such asLabeledObjects, to other contexts.
4.8. Should fetchingrequest be blocked as COWL?
Given aRequestrequest, a user agent determines whether theRequestrequest should proceed or not via the following algorithm:
Letcontext be theclient associated with therequest.
Ifcontext is null, letcontext be theincumbent settings object.
Note, theclient associated with therequest is null whennavigating, so we use theincumbent settings object to get theCOWL state of thecontext that initiated the request.
Letstate be theCOWL state retrieved via theenvironment settings objectcontext.
If thestateconfinement mode is not enabled, returnallowed and terminated this algorithm.
Letconf be thestateeffective confidentiality label.
LetdstConf be theLabel created by invoking theLabel(origin) constructor with theurl associated with therequest.
IfdstConfsubsumesconf, returnallowed.
Else:
If therequest is anavigation request and thecontext is atop-level browsing context, the user agent MAY returnallowed, but MUST indicate to the user that data labeledconf may have been leaked due to the navigation. It is RECOMMENDED that user agents give users the options to block the navigation, e.g., via a pop-up dialog.
We can simply disallow leaks via top-level navigation at the cost of potentially forcing users to navigate away by closing tabs or inputting another URL via the address bar. Feedback on this would be welcome.
Else, returnblocked.
Note, the integrity label of the current context is not used in this algorithm since, conceptually, the integrity label of a server is theempty label and, thus, always subsumed. Server operators SHOULD check theSec-COWL
request header to ensure untrustworthy data does not affect the computation in an unsafe way.
4.9. Processresponse torequest as COWL
This algorithm is also used to set theCOWL state for new documents and Workers according to server-supplied thelabeled context metadata.
Given aRequestrequest andResponseresponse, a user agent determines whether the response should be returned via the following algorithm:
If theresponse’sheader list has noheader whosename is
Sec-COWL
, returnallowed and terminate this algorithm.Letdestination be therequest’sdestination.
Lettype be therequest’stype.
LetMIMEType be the result ofextracting a MIME type fromresponse’sheader list.
Letcontext be theclient associated with therequest.
Ifcontext is null, letcontext be theincumbent settings object.
Note, theclient associated with therequest is null whennavigating, so we use theincumbent settings object to get or set theCOWL state of thecontext that initiated the request.
Letstate be theCOWL state retrieved via theenvironment settings objectcontext.
Letmetadata be thefirstheader whosename is
Sec-COWL
in theresponse’sheader list.Ifdestination is
"document"
,"worker"
or"serviceworker"
:Letself be the serialization of theorigin retrieved via theenvironment settings objectcontext.
Letconf,int,priv be the result of calling theparse labeled context metadata algorithm withmetadata andself.
If eitherconf,int, orpriv are null, returnblocked.
Else:
Set thestatecontext confidentiality label toconf.
Set thestatecontext integrity label toint, if thestateeffective integrity label subsumesint.
Note, by performing thelabel subsumption check before setting thecontext privilege (next step), thecontext integrity label can be upgraded from theempty label, while allowing thecontext privilege to also be dropped.
Should the user agent warn the user if the server provided an integrity label that it is not allowed to provide?
Set thestatecontext privilege topriv, ifpriv is adelegated privilege of thestatecontext privilege.
Should the user agent warn the user if the server provided a privilege that it is not allowed to provide?
Enableconfinement mode forstate.
Returnallowed.
Else:
Letconf andint be the results of calling theparse labeled data metadata withmetadata andself.
If eitherconf orint is null, returnblocked and terminate this algorithm.
If thestateeffective confidentiality label subsumesconf andint subsumes thestateeffective integrity label, returnallowed.
Else, returnblocked.
Note, COWL conservatively blocks a response that is potentially more confidential or less trustworthy than the context making the request. In future versions of COWL, certain responses (e.g., images) which are only not as trustworthy as thecontext integrity label may be allowed by the user agent.
4.10. Parse labeled data metadata
Toparselabeled data metadatametadata for originself, the user agent MUST use an algorithm equivalent to the following:
Letconf be null.
Letint be null.
For each non-empty token returned bystrictly splitting the stringmetadata on the character U+003B SEMICOLON (
;
):Collect a sequence of characters that are notspace characters. The collected characters are thedirective name.
If there are characters remaining intoken, skip ahead exactly one character (which must be aspace character).
The remaining characters intoken (if any) are thedirective value.
Letlabel value be thelabel returned by calling thefromJSON() function with thedirective value andself. If the function threw an exception, ignore this instance of the directive and continue to the next token.
Ifdirective name is
data-confidentiality
andconf is null, letconf belabel value.Else, ifdirective name is
data-integrity
andint is null, letint belabel value.Else, ignore this instance of the directive and continue to the next token.
Returnconf andint.
4.11. Parse labeled context metadata
Toparselabeled context metadatametadata for originself, the user agent MUST use an algorithm equivalent to the following:
Letconf be null.
Letint be null.
Letpriv be null.
For each non-empty token returned bystrictly splitting the stringmetadata on the character U+003B SEMICOLON (
;
):Collect a sequence of characters that are notspace characters. The collected characters are thedirective name.
If there are characters remaining intoken, skip ahead exactly one character (which must be aspace character).
The remaining characters intoken (if any) are thedirective value.
Letlabel value be thelabel returned by calling thefromJSON() function with thedirective value andself. If the function threw an exception, ignore this instance of the directive and continue to the next token.
Ifdirective name is
ctx-confidentiality
andconf is null, letconf belabel value.Else, ifdirective name is
ctx-integrity
andint is null, letint belabel value.Else, ifdirective name is
ctx-privilege
andpriv is null, letpriv be a newly createdprivilege whoseinternal privilege label is set tolabel value.Else, ignore this instance of the directive and continue to the next token.
Returnconf,int, andpriv.
5.IANA Considerations
5.1. TheSec-COWL
HTTP Header Field
The permanent message header field registry should be updated with the following registration[RFC3864]:- Header field name
- Sec-COWL
- Applicable protocol
- http
- Status
- standard
- Author/Change controller
- W3C
- Specification document
- This specification (See§3.5 The Sec-COWL HTTP Headers)
5.2. Theapplication/labeled-json
MIME media type
- Type name
- application
- Subtype name
- labeled-json
- Required parameters
- Same as for
application/json
.[JSON] - Optional parameters
- Same as for
application/json
.[JSON] - Encoding considerations
- Same as for
application/json
.[JSON] - Security considerations
- Same as for
application/json
.[JSON] - Interoperability considerations
- Same as for
application/json
.[JSON] - Published specification
- Labeling a resource with the
application/labeled-json
type asserts that the resource is a JSON text that consists of an object with a single entry called"confidentiality"
consisting of an array of entries, each of which consists of an array of strings, a single entry called"integrity"
consisting of an array of entries, each of which consists of an array of strings, and a single entry called"object"
consisting of a JSON object. The relevant specifications are the JSON specification and this specification.[JSON] - Author/Change controller
- W3C
6.Acknowledgements
Thanks to Dan Boneh, Brendan Eich, Lon Ingram, Brad Hill, Dave Herman, Bobby Holley, Brad Karp, Jonathan Kingston, Petr Marchenko, David Mazières, Devon Rifkin, Alejandro Russo, and Brian Smith for influencing (directly or otherwise) the design of COWL and/or their comments on this document.