Secure Contexts

W3C Working Draft,

This version:
http://www.w3.org/TR/2016/WD-secure-contexts-20160715/
Latest published version:
http://www.w3.org/TR/secure-contexts/
Editor's Draft:
https://w3c.github.io/webappsec-secure-contexts/
Previous Versions:
http://www.w3.org/TR/2016/WD-secure-contexts-20160426/
Version History:
https://github.com/w3c/webappsec-secure-contexts/commits/master/index.src.html
Feedback:
[email protected] with subject line “[secure-contexts] … message topic …” (archives)
Editor:
(Google Inc.)
Former Editor:
Yan Zhu (Brave)
Participate:
File an issue (open issues)

Abstract

This specification defines "secure contexts", thereby allowing user agent implementers and specification authors to enable certain features only when certain minimum standards of authentication and confidentiality are met.

Status of this document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document was published by the Web Application Security Working Group as a Working Draft. This document is intended to become a W3C Recommendation.

The (archived) public mailing list [email protected] (see instructions) is preferred for discussion of this specification. When sending e-mail, please put the text “secure-contexts” in the subject, preferably like this: “[secure-contexts] …summary of comment…

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by the Web Application Security Working Group.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 September 2015 W3C Process Document.

1. Introduction

This section is not normative.

As the web platform is extended to enable more useful and powerful applications, it becomes increasingly important to ensure that the features which enable those applications are enabled only in contexts which meet a minimum security level. This document describes threat models for feature abuse on the web (see §4.1 Threat Models) and outlines normative requirements which should be incorporated into documents specifying new features (see §7 Implementation Considerations).

The most obvious of the requirements discussed here is that application code with access to sensitive or private data be delivered confidentially over authenticated channels that guarantee data integrity. Delivering code securely cannot ensure that an application will always meet a user’s security and privacy requirements, but it is a necessary precondition.

Less obviously, application code delivered over an authenticated and confidential channel isn’t enough in and of itself to limit the use of powerful features by non-secure contexts. As §4.2 Ancestral Risk explains, cooperative frames can be abused to bypass otherwise solid restrictions on a feature. The algorithms defined below ensure that these bypasses are difficult and user-visible.

The following examples summarize the normative text which follows:

1.1. Top-level Documents

Top-level documents are secure as long as they don’t have a non-secure opener browsing context. This is a bit convoluted, so let’s go straight to the examples:

http://example.com/ opened in a top-level browsing context is not a secure context, as it was not delivered over an authenticated and encrypted channel.

http://example.com/

https://example.com/ opened in a top-level browsing context is a secure context, as it was delivered over an authenticated and encrypted channel.

https://example.com/

If a secure context opens https://example.com/ in a new window, that new window will be a secure context, as it is both secure on its own merits, and was opened from a secure context: https://secure.example.com/ https://another.example.com/

If a non-secure context opens https://example.com/ in a new window, then things are more complicated. The new window’s status depends on how it was opened. If the non-secure context can obtain a reference to the secure context, or vice-versa, then the new window is not a secure context.

This means that the following will both produce non-secure contexts:

Link!
      

http://non-secure.example.com/ https://another.example.com/

The link can be broken via the noopener link relation, meaning that the following will both produce secure contexts:

noopener" target="_blank">Link!
      

http://non-secure.example.com/ https://another.example.com/

W3C’s HTML has only an extremely partial port of the noopener concept.

1.2. Framed Documents

Framed documents can be secure contexts if they are delivered from potentially trustworthy origins, and if they’re embedded in a secure context. That is:

If https://example.com/ opened in a top-level browsing context opens https://sub.example.com/ in a frame, then both are secure contexts, as both were delivered over authenticated and encrypted channels.

https://example.com/ https://sub.example.com/

If https://example.com/ was somehow able to frame http://non-secure.example.com/ (perhaps the user has overridden mixed content checking?), the top-level frame would remain secure, but the framed content is not a secure context.

https://example.com/ http://non-secure.example.com/

If, on the other hand, https://example.com/ is framed inside of http://non-secure.example.com/, then it is not a secure context, as its ancestor is not delivered over an authenticated and encrypted channel.

http://non-secure.example.com/ https://example.com/

1.3. Web Workers

Dedicated Workers are similar in nature to framed documents. They’re secure contexts when they’re delivered from potentially trustworthy origins, only if their owner is itself a secure context:

If https://example.com/ in a top-level browsing context runs https://example.com/worker.js, then both the document and the worker are secure contexts.

https://example.com/ https://example.com/worker.js

If http://non-secure.example.com/ in a top-level browsing context frames https://example.com/, which runs https://example.com/worker.js, then neither the framed document nor the worker are secure contexts.

http://non-secure.example.com/ https://example.com/ https://example.com/worker.js

1.4. Shared Workers

Multiple contexts may attach to a Shared Worker. If a secure context creates a Shared Worker, then it is a secure context, and may only be attached to by other secure contexts. If a non-secure context creates a Shared Worker, then it is not a secure context, and may only be attached to by other non-secure contexts.

If https://example.com/ in a top-level browsing context runs https://example.com/worker.js as a Shared Worker, then both the document and the worker are considered secure contexts.

https://example.com/ https://example.com/worker.js

https://example.com/ in a different top-level browsing context (e.g. in a new window) is a secure context, so it may access the secure shared worker:

https://example.com/ https://example.com/worker.js https://example.com/

https://example.com/ nested in http://non-secure.example.com/ may not connect to the secure worker, as it is not a secure context.

https://example.com/ https://example.com/worker.js http://non-secure.example.com/ https://example.com/ X

Likewise, if https://example.com/ nested in http://non-secure.example.com/ runs https://example.com/worker.js as a Shared Worker, then both the document and the worker are considered non-secure.

http://non-secure.example.com/ https://example.com/ https://example.com/worker.js https://example.com/ X

1.5. Service Workers

Service Workers are always secure contexts. Only secure contexts may register them, and they may only have clients which are secure contexts.

If https://example.com/ in a top-level browsing context registers https://example.com/service.js, then both the document and the Service Worker are considered secure contexts.

https://example.com/ https://example.com/service.js

2. Framework

An environment settings object is considered a secure context if the algorithm in §3.1 Is settings object a secure context? returns "Secure", and a non-secure context otherwise.

Likewise, a global object is considered a secure context if its relevant settings object is a secure context.

2.1. Intergration with WebIDL

This section is non-normative.

A new [SecureContext] attribute is available for operators, which ensures that they will only be exposed into secure contexts. The following example should help:

interface ExampleFeature {
  // This call will succeed in all contexts.
  Promise <double> calculateNotSoSecretResult();

  // This operation will not be exposed to a non-secure context.
  [SecureContext] Promise<double> calculateSecretResult();

  // The same applies here: the operation will not be exposed to a non-secure context.
  [SecureContext] boolean getSecretBoolean();
};

[SecureContext]
interface SecureFeature {
  // This interface will not be exposed to non-secure contexts.
  Promise<any> doAmazingThing();
};

Specification authors are encouraged to use this attribute when defining new features.

2.2. Modifications to HTML

2.2.1. Shared Workers

The SharedWorker() constructor will throw a SecurityError exception if a secure context attempts to attach to an Worker which is not a secure context, and if a non-secure context attempts to attach to a Worker which is a secure context. The constructor is modified as follows:

  1. As the first substep of the SharedWorker() constructor’s current step 6.7 ("If worker global scope is not null, then run these steps:"), run the following step:

    1. If the result of executing §3.1 Is settings object a secure context? on the current settings object does not match the result of executing the same algorithm on worker global scope’s relevant settings object, then throw a SecurityError exception, and abort these steps.

Upstreaming to WHATWG is underway.

It’s not clear to me how the W3C’s [WEBWORKERS] document is updated. It looks like it’s pulling content from the WHATWG upstream, which means that the PR linked above should flow into it? But that document hasn’t been updated since 2015, so...

2.2.2. Feature Detection

To determine whether a context is capable of making use of features which require secure contexts, a simple boolean attribute is added to the global object:

partial interface WindowOrWorkerGlobalScope {
  readonly attribute boolean isSecureContext;
};
WindowOrWorkerGlobalScope does not appear to be defined in W3C’s HTML. For the purposes of that specification, the IDL above could be interpreted as:
interface GlobalSecureContext {
  readonly attribute boolean isSecureContext;
};
Window implements GlobalSecureContext;
WorkerGlobalScope implements WindowBase64;

Filed as w3c/html#522.

The isSecureContext attribute’s getter returns true if §3.1 Is settings object a secure context? returns "Secure" when executed upon this global object’s relevant settings object, and false otherwise.

3. Algorithms

3.1. Is settings object a secure context?

Given an environment settings object (settings) this algorithm returns "Secure" if the object represents a context which the user agent obtained via a secure channel, and "Not Secure" otherwise.

  1. Let global be settings’s global object.

  2. If global is a WorkerGlobalScope, then:

    1. For each Document (document) in global’s list of the worker’s Documents:

      1. If §3.1 Is settings object a secure context? returns "Not Secure" when executed upon document’s relevant settings object, return "Not Secure".

  3. Assert: global is a Window.

  4. If settings object’s responsible document has an creator browsing context whose creator context security is "Not Secure", return "Not Secure".

    Note: Since we take account of creator browsing contexts' status, a popups' status depends on how it is opened, as discussed in §1.1 Top-level Documents.

    The 'creator context security' concept doesn’t yet exist, other than in an open PR against WHATWG’s HTML.

    The 'creator context security' concept doesn’t yet exist in W3C’s HTML.

  5. If settings object’s HTTPS state is "modern", return "Secure".

    Most of the time, this check will be enough to determine whether a particular context was securely delivered. Documents delivered over TLS will have their HTTPS state set, and srcdoc Documents inherit their ancestor’s HTTPS state (as do other kinds of requests which inherit their requestor’s origin: see the basic fetch algorithm for details on some of these [FETCH]).

    We only continue past this check in order to allow resources delivered from "trustworthy" but unauthenticated locations like http://127.0.0.1/ to be treated as creating a secure context.

  6. Let origin be settings object’s origin.

  7. If origin is an opaque origin, set origin to the origin of settings object’s creation URL.

    Note: We use the origin of the URL here because sandboxed content that is treated as being in a unique origin (e.g.