Content Security Policy: Cookie Controls

W3C First Public Working Draft,

This version:
http://www.w3.org/TR/2015/WD-csp-cookies-20151215/
Latest version:
http://www.w3.org/TR/csp-cookies/
Editor's Draft:
https://w3c.github.io/webappsec-csp/cookies/
Feedback:
public-webappsec@w3.org with subject line “[csp-cookies] … message topic …” (archives)
Editor:
(Google Inc.)

Abstract

This document defines mechanisms by which web developers can limit the ways in which cookies may be set in the context of their sites and applications.

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 public-webappsec@w3.org (see instructions) is preferred for discussion of this specification. When sending e-mail, please put the text “csp-cookies” in the subject, preferably like this: “[csp-cookies] …summary of comment…

This document is a First Public Working Draft.

Publication as a First Public 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.

Table of Contents

1. Introduction

This section is not normative.

Cookies are an HTTP state management mechanism that web developers rely on heavily for important things like authentication. They are also quite fragile, and have scoping rules that don’t mesh well with the origin model that developers are familiar with. Cookies flow freely between schemes by default, can be set from subdomains or limited to paths, and ignore ports entirely. The disconnect between cookies and other types of storage opens up a number of risks that are difficult to fully mitigate. See [YUMMY-COOKIES] for some real-world examples of problems that have cropped up in the past.

This document defines mechanisms which allow developers to limit the ways in which cookies can be set for a given protected resource.

1.1. Examples

MegaCorp Inc. hosts a number of pages which have no real need to write cookies. Following the principle of least privilege, the clever developers responsible for those pages send the following headers along with every HTTP response, ensuring that no cookies can be set via Set-Cookie or document.cookie:
Content-Security-Policy: cookie-scope none
MegaCorp Inc. hosts a number of pages on http://non-secure.example.com which need to write cookies, but don’t need those cookies to span subdomains. The following header ensures that cookies can only be set via Set-Cookie or document.cookie if those cookies are "host only" (e.g. the cookie’s domain attribute is empty):
Content-Security-Policy: cookie-scope host

That is, the following code would set a cookie:

document.cookie = "key=value";

And the following would not:

document.cookie = "key=value; domain=example.com";
MegaCorp Inc. hosts a number of pages on https://secure.example.com which need to write cookies, but don’t need those cookies to span subdomains. They’ll certainly set the host property, just like the previous example, but since this is a secure site, they also wish to ensure that any cookies they set also contain the secure attribute. They can do so with the following header:
Content-Security-Policy: cookie-scope host secure

That is, the following code would set a cookie:

document.cookie = "key=value; secure";

And the following would not:

document.cookie = "key=value";
document.cookie = "key=value; domain=example.com; secure";

cookie-scope is a Content Security Policy directive [CSP] which restricts the cookies [RFC6265] which can be set in a particular context. The syntax is described by the following ABNF grammar [RFC5234] (including the RWS rule from [RFC7230]):

directive-name = "cookie-scope"
directive-value = scoping-rules *( RWS scoping-rules )
scoping-rules = "host" / "http" / "none" / "secure"

The directive has one of four values:

  1. "host" allows "host only" cookies to be set, but will block setting cookies which set a domain attribute.

  2. "http" allows cookies to be set via the Set-Cookie HTTP header, but not via document.cookie.

  3. "none" blocks all cookies.

  4. "secure" allows cookies to be set with a secure attribute, and will block setting any non-secure cookies.

These values MAY be combined in order to tighten the restrictions on a cookie. That is, if both "host" and "secure" are present, then cookies may only be set which are both secure and host-only. If "none" is present with any combination of the other values, no cookies may be set.

Erik Nygren proposed adding path restrictions as well. Is that worthwhile?

2.1. Processing Model

After step 10 of the storage algorithm in Section 5.3 of RFC 6265, a cookie object has been built. Insert the following validation step before proceeding to the current step 11:

  1. If §3.1 Is cookie blocked for settings? returns "Blocked" when executed upon cookie and the incumbent settings object, abort these steps without modifying the cookie store.

Monkey patching! Hey, maybe it’s time to reopen that cookie RFC after all, eh @mnot? :)

We’ll need a mechanism to restrict reading from document.cookie, but I’d like something less specific than cookie-scope disable-dom-access or something similar. The linked GitHub bug is a proposal that’s a bit more general and widely applicable. <https://github.com/w3c/webappsec-csp/issues/42>

3. Algorithms

Given a cookie (cookie), and an environment settings object (settings), this algorithm returns "Allowed" if cookie can be written, and "Blocked" if it violates one or more of settings’s enforced Content Security Policies:

  1. Let status be "Allowed".

  2. For each policy in settings’s monitored Content Security Policies:

    1. If §3.2 Does cookie violate policy? returns "Violates" when executed upon the cookie and policy, report a violation.

      Note: We do not touch status here, as we’re only evaluating the monitored policies.

  3. For each policy in settings’s enforced Content Security Policies:

    1. If §3.2 Does cookie violate policy? returns "Violates" when executed upon the cookie and policy, report a violation, and set status to "Blocked":

  4. Return status.

3.2. Does cookie violate policy?

  1. Let scope be the result of executing §3.3 Parse string as a cookie-scope value on policy’s cookie-scope directive.

  2. If any of the following conditions are met, return "Violates":

    1. scope contains "host", and the cookie’s host-only-flag is false.

    2. scope contains "http", and the cookie was received from a "non-HTTP" API.

    3. scope contains "none".

    4. scope contains "secure", and the cookie’s secure-only-flag is false.

  3. Return "Does not violate".

3.3. Parse string as a cookie-scope value

Given a string (string), this algorithm returns a set of the valid cookie-scope values the string represents. Invalid values are ignored:

  1. Strip leading and trailing whitespace from string.

  2. Let values be an empty set.

  3. For each token in the list generated by splitting string on spaces:

    1. If token matches the grammar for scoping-rules, insert token into values.

  4. Return values.

4. Security Considerations

4.1. Existing Cookies

Note that the mechanisms defined here do not protect against cookies that already exist in a user’s cookie store. Those cookies are delivered along with the HTTP request, before Content Security Policy can be delivered and applied. It is possible that future work like [CSP-PINNING] might enable these kinds of a priori restrictions, but, even then, CSP should be seen as a mitigation strategy, layered on top of filters and sanity checks for incoming data.

5. Acknowledgements

Mark Nottingham proposed this directive several years ago. Sorry it took so long, Mark!

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words "for example" or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word "Note" and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[CSP]
Brandon Sterne; Adam Barth. Content Security Policy 1.0. 19 February 2015. NOTE. URL: http://www.w3.org/TR/CSP1/
[CSP3]
Mike West; Daniel Veditz. Content Security Policy. ED. URL: https://w3c.github.io/webappsec/specs/content-security-policy/
[HTML5]
Ian Hickson; et al. HTML5. 28 October 2014. REC. URL: http://www.w3.org/TR/html5/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC5234]
D. Crocker, Ed.; P. Overell. Augmented BNF for Syntax Specifications: ABNF. January 2008. Internet Standard. URL: https://tools.ietf.org/html/rfc5234
[RFC6265]
A. Barth. HTTP State Management Mechanism. April 2011. Proposed Standard. URL: https://tools.ietf.org/html/rfc6265
[RFC6454]
A. Barth. The Web Origin Concept. December 2011. Proposed Standard. URL: https://tools.ietf.org/html/rfc6454
[RFC7230]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7230
[URL]
Anne van Kesteren; Sam Ruby. URL. 9 December 2014. WD. URL: http://www.w3.org/TR/url-1/

Informative References

[CSP-PINNING]
Mike West. Content Security Policy: Pinning. FPWD. URL: https://w3c.github.io/webappsec/specs/csp-pinning/
[YUMMY-COOKIES]
Vincent Marti. Yummy cookies across domains. URL: https://github.com/blog/1466-yummy-cookies-across-domains

Issues Index

Erik Nygren proposed adding path restrictions as well. Is that worthwhile?
Monkey patching! Hey, maybe it’s time to reopen that cookie RFC after all, eh @mnot? :)
We’ll need a mechanism to restrict reading from document.cookie, but I’d like something less specific than cookie-scope disable-dom-access or something similar. The linked GitHub bug is a proposal that’s a bit more general and widely applicable. <https://github.com/w3c/webappsec-csp/issues/42>