Content Security Policy: Cookie Controls

A Collection of Interesting Ideas,

This version:
https://w3c.github.io/webappsec/specs/csp-cookies/
Latest version:
http://www.w3.org/TR/csp-cookies/
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.

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.

Note: [ORIGIN-COOKIES] could resolve some of the issues here in a different way, but it’s unclear if those will ever be adopted.

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 scope in which cookies [RFC6265] can be set. 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" / "none" / "secure"

The directive has one of three values:

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

  2. "none" blocks all cookies.

  3. "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 object? 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? :)

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 "none".

    3. 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

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.

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/
[RFC6454]
Adam Barth. The Web Origin Concept. RFC. URL: http://www.ietf.org/rfc/rfc6454.txt
[RFC7230]
Roy T. Fielding; Julian F. Reschke. HTTP/1.1 Message Syntax and Routing. RFC. URL: http://www.ietf.org/rfc/rfc7230.txt
[URL]
Anne van Kesteren. URL. Living Standard. URL: https://url.spec.whatwg.org/
[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

Informative References

[CSP-PINNING]
Mike West. Content Security Policy: Pinning. FPWD. URL: https://w3c.github.io/webappsec/specs/csp-pinning/
[ORIGIN-COOKIES]
Mike West. Origin Cookies. ID. URL: https://tools.ietf.org/html/draft-west-origin-cookies
[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? :)