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
Set-Cookie
or document.cookie
:
Content-Security-Policy: cookie-scope none
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";
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";
2. The cookie-scope
directive
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:
-
"host" allows "host only" cookies to be set, but will block setting cookies which set a
domain
attribute. -
"none" blocks all cookies.
-
"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:
- 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
3.1. Is cookie blocked for settings object?
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:
-
Let status be "
Allowed
". -
For each policy in settings’s monitored Content Security Policies:
-
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.
-
-
For each policy in settings’s enforced Content Security Policies:
-
If §3.2 Does cookie violate policy? returns "
Violates
" when executed upon the cookie and policy, report a violation, and set status to "Blocked
":
-
-
Return status.
3.2. Does cookie violate policy?
-
Let scope be the result of executing §3.3 Parse string as a cookie-scope value on policy’s cookie-scope directive.
-
If any of the following conditions are met, return "
Violates
": -
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:
-
Strip leading and trailing whitespace from string.
-
Let values be an empty set.
-
For each token in the list generated by splitting string on spaces:
-
If token matches the grammar for scoping-rules, insert token into values.
-
-
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!