Summary of major differences between COWL and Suborigins

Hi folks. Per Brad's request, I've written up a summary of the differences
between the COWL <https://www.w3.org/TR/COWL/> and Suborigins
<https://w3c.github.io/webappsec-suborigins/> proposals, since there has
been some confusion about the relationship between the two. I look forward
to thoughts, corrections, and amendments, so don't be shy :-)

COWL provides a system for labeling data programmatically and setting
policies on how labeled data may be used. In turn, this restricts
resources/privileges that a given execution context may access, including
same origin/host restricted resources such as cookies and storage, and
cross-origin based resources, such as values received via postMessage() or
a CORS response.

Suborigins extends the same-origin policy by providing a mechanism for
creating a namespaced origin. Two execution contexts with the same
namespace, scheme, host, and port are treated as same-origin, while two
execution contexts with the same scheme, host, and port but different
namespaces are treated as different origins and therefore are isolated from
each other via standard same-origin policy rules.

While COWL and Suborigins differ in many small ways, there are several
macro differences that are quite important. COWL allows a developer to
apply the principle of least privilege to trusted but potentially buggy
code. Suborigins, on the other hand, provide a much coarser grained tool to
isolate code entirely. Since it places the entire context into a separate
origin, that context, even if malicious, will never be able to access or
leak anything that is not explicitly given to the Suborigin.

Thus, the two systems provide fundamentally different, but potentially
complementary, mechanisms for different threats: COWL for reducing the
privilege of a context and Suborigins for isolating a context completely.
These can be used separately for different types of applications or may be
used in tandem.

For example, consider hosting an untrusted application on
www.example.com/app. COWL allows us to say that /app doesn’t get access to
cookies or that postMessage events only get sent to particular origins,
while Suborigins allow us to say /app gets to treat its cookies as a
subdomain would and gives us a new namespaced value for event.origin in
MessageEvents. These are complementary mechanisms. And, of course, it is
not hard to imagine an application with all of these properties so both
COWL and Suborigins are useful.

Thinking about Cross-Site Scripting specifically, COWL cannot prevent an
XSS from executing in any part of an origin. Furthermore, even if the
sensitive data in that origin is restricted, an XSS can always drop
privileges to a restricted label and exfiltrate the data using side
channels. However, using COWL, an origin can control what information flows
into another origin in the first place, potentially recognizing a context
as vulnerable, it may be able to prevent the accidental leakage of data
into a compromised application. Suborigins, on the other hand, create a new
security context, and if an XSS occurs in the Suborigin, it cannot access
other Suborigins or the original origin. Thus, an XSS can be contained to
executing within a Suborigin context.

Another important difference is in implementation. To be truly useful, COWL
requires programmatic changes to an application to be data-flow aware since
the policy is defined by the program itself. This includes making Labels to
mark the integrity or confidentiality of data, as well as dropping
privileges. Suborigins are applied declaratively in a header, and the
policy lives fully in the header. This may require programmatic changes to
the application, similar to moving an origin to a subdomain, but
potentially few or no changes needed to the application, with the cost that
it is a very coarse grained security mechanism.

In summary, COWL and Suborigins provide two fundamentally different
mechanisms with different goals. COWL provides a way to enforce least
privilege within an application so that it is harder to compromise.
Suborigins, on the other hand, provide a new way to enforce privilege
separation in the same way that origins do, but more fine grained.

--Joel Weinberger

Received on Thursday, 14 January 2016 21:44:24 UTC