RFC 6265
HTTP State Management Mechanism
Abstract β¨
okay bestie, this doc defines the HTTP Cookie and Set-Cookie header fields πͺ Servers use them to store state (called cookies) at HTTP user agents, so a server can keep a stateful session going even though HTTP is mostly stateless π§ Cookies have lots of historical infelicities that hurt their security and privacy, ngl, but the Cookie and Set-Cookie headers are still everywhere on the Internet π This document obsoletes RFC 2965.
Status of This Memo π
this is an Internet Standards Track document π
it's a product of the Internet Engineering Task Force (IETF) πΈ it has the consensus of the IETF community, got public review, and was approved for publication by the Internet Engineering Steering Group (IESG) π for more on Internet Standards, check Section 2 of RFC 5741.
info about the current status of this doc, any errata, and how to send feedback is at http://www.rfc-editor.org/info/rfc6265 π¦
Copyright Notice π
Copyright (c) 2011 IETF Trust and the persons identified as the document authors. All rights reserved.
so this doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stand on the date it was published π please actually read those, because they spell out your rights and restrictions for this doc. Code Components pulled out of this doc must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as described in the Simplified BSD License π«Ά
this doc might contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008 π₯Ή the people controlling the copyright in some of that material might not have granted the IETF Trust the right to allow modifications outside the IETF Standards Process. So unless you get an adequate license from whoever controls that copyright, this doc may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process. The exceptions are formatting it for publication as an RFC or translating it into languages other than English π
Table of Contents π
1. Introduction ....................................................3
2. Conventions .....................................................4
2.1. Conformance Criteria .......................................4
2.2. Syntax Notation ............................................5
2.3. Terminology ................................................5
3. Overview ........................................................6
3.1. Examples ...................................................6
4. Server Requirements .............................................8
4.1. Set-Cookie .................................................8
4.1.1. Syntax ..............................................8
4.1.2. Semantics (Non-Normative) ..........................10
4.2. Cookie ....................................................13
4.2.1. Syntax .............................................13
4.2.2. Semantics ..........................................13
5. User Agent Requirements ........................................14
5.1. Subcomponent Algorithms ...................................14
5.1.1. Dates ..............................................14
5.1.2. Canonicalized Host Names ...........................16
5.1.3. Domain Matching ....................................16
5.1.4. Paths and Path-Match ...............................16
5.2. The Set-Cookie Header .....................................17
5.2.1. The Expires Attribute ..............................19
5.2.2. The Max-Age Attribute ..............................20
5.2.3. The Domain Attribute ...............................20
5.2.4. The Path Attribute .................................21
5.2.5. The Secure Attribute ...............................21
5.2.6. The HttpOnly Attribute .............................21
5.3. Storage Model .............................................21
5.4. The Cookie Header .........................................25
6. Implementation Considerations ..................................27
6.1. Limits ....................................................27
6.2. Application Programming Interfaces ........................27
6.3. IDNA Dependency and Migration .............................27
7. Privacy Considerations .........................................28
7.1. Third-Party Cookies .......................................28
7.2. User Controls .............................................28
7.3. Expiration Dates ..........................................29
8. Security Considerations ........................................29
8.1. Overview ..................................................29
8.2. Ambient Authority .........................................30
8.3. Clear Text ................................................30
8.4. Session Identifiers .......................................31
8.5. Weak Confidentiality ......................................32
8.6. Weak Integrity ............................................32
8.7. Reliance on DNS ...........................................33
9. IANA Considerations ............................................33
9.1. Cookie ....................................................34
9.2. Set-Cookie ................................................34
9.3. Cookie2 ...................................................34
9.4. Set-Cookie2 ...............................................34
10. References ....................................................35
10.1. Normative References .....................................35
10.2. Informative References ...................................35
Appendix A. Acknowledgements ......................................37
1. Introduction β¨
okay so this doc defines the HTTP Cookie and Set-Cookie header fields π With the Set-Cookie header, an HTTP server can pass name/value pairs and their associated metadata (called cookies) to a user agent π When the user agent makes later requests to that server, it uses the metadata and other info to decide whether to send those name/value pairs back in the Cookie header π¦
cookies look simple, but they're giving complexity π For example, the server sets a scope for each cookie when it sends it to the user agent. That scope says the maximum amount of time the user agent should return the cookie, which servers it should go back to, and which URI schemes the cookie applies to πΊοΈ
for historical reasons, cookies come with a bunch of security and privacy infelicities π A server can mark a cookie as meant for "secure" connections, but the Secure attribute does not provide integrity when there's an active network attacker. Also, cookies for a given host are shared across all the ports on that host, even though the usual "same-origin policy" that web browsers use isolates content fetched from different ports π
there are two audiences for this spec: developers of cookie-generating servers and developers of cookie-consuming user agents π§βπ»
to maximize interoperability with user agents, servers SHOULD limit themselves to the well-behaved profile defined in Section 4 when generating cookies π«Ά
User agents MUST implement the more liberal processing rules defined in Section 5, so they can maximize interoperability with existing servers that don't conform to the well-behaved profile in Section 4 π₯
this doc specifies the syntax and semantics of these headers as they're actually used on the Internet π Like, it does not create new syntax or semantics beyond what's in use today. The cookie generation recommendations in Section 4 are a preferred subset of current server behavior, and even the more liberal processing algorithm in Section 5 doesn't recommend every syntactic and semantic variation in use today. When some existing software differs from the recommended protocol in significant ways, the doc has a note explaining the difference π
before this doc, there were at least three descriptions of cookies: the so-called "Netscape cookie specification" [Netscape], RFC 2109 [RFC2109], and RFC 2965 [RFC2965]. But none of them describe how the Cookie and Set-Cookie headers are actually used on the Internet (see [Kri2001] for historical context) π Regarding previous IETF specs of HTTP state management mechanisms, this doc requests the following actions:
- Change the status of [RFC2109] to Historic (it has already been obsoleted by [RFC2965]).
- Change the status of [RFC2965] to Historic.
- Indicate that [RFC2965] has been obsoleted by this document.
so in particular, by moving RFC 2965 to Historic and obsoleting it, this doc deprecates the use of the Cookie2 and Set-Cookie2 header fields πͺ¦
2. Conventions πΈ
2.1. Conformance Criteria
the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this doc are to be interpreted as described in [RFC2119] π
requirements written as imperatives inside algorithms (stuff like "strip any leading space characters" or "return false and abort these steps") get the meaning of the key word ("MUST", "SHOULD", "MAY", etc.) used when the algorithm was introduced π§
conformance requirements written as algorithms or specific steps can be implemented in any manner, as long as the end result is equivalent β¨ The algorithms in this spec are meant to be easy to understand, and they are not meant to be performant π’
2.2. Syntax Notation
this spec uses the Augmented Backus-Naur Form (ABNF) notation of [RFC5234] π§©
the following core rules are included by reference, as defined in [RFC5234], Appendix B.1: ALPHA (letters), CR (carriage return), CRLF (CR LF), CTLs (controls), DIGIT (decimal 0-9), DQUOTE (double quote), HEXDIG (hexadecimal 0-9/A-F/a-f), LF (line feed), NUL (null octet), OCTET (any 8-bit sequence of data except NUL), SP (space), HTAB (horizontal tab), CHAR (any [USASCII] character), VCHAR (any visible [USASCII] character), and WSP (whitespace) π
the OWS (optional whitespace) rule is used where zero or more linear whitespace characters MAY appear:
OWS = *( [ obs-fold ] WSP )
; "optional" whitespace
obs-fold = CRLF
OWS SHOULD either not be produced or be produced as a single SP character. π«§
2.3. Terminology π
Okay bestie, the words user agent, client, server, proxy, and origin server mean exactly what they mean in the HTTP/1.1 spec ([RFC2616], Section 1.3). No new definitions, no drama π
The request-host is the name of the host, as known by the user agent, that it's sending an HTTP request to or getting an HTTP response from. Basically, it's the host the user agent sent the matching request to πΈ
The term request-uri is defined in Section 5.1.2 of [RFC2616] π
Two sequences of octets case-insensitively match each other if and only if they're equivalent under the i;ascii-casemap collation defined in [RFC4790] π₯
The term string means a sequence of non-NUL octets β¨
3. Overview π¦
This section lays out how an origin server sends state info to a user agent, and how the user agent sends that state back to the origin server π
To store state, the origin server includes a Set-Cookie header in an HTTP response. Then, in later requests, the user agent returns a Cookie request header. That Cookie header holds the cookies the user agent got in earlier Set-Cookie headers. The origin server is free to ignore the Cookie header or use its contents for an application-defined purpose π
Origin servers MAY send a Set-Cookie response header with any response. User agents MAY ignore Set-Cookie headers in responses with 100-level status codes, but they MUST process Set-Cookie headers in every other response, including the 400- and 500-level ones π An origin server can include multiple Set-Cookie header fields in a single response. Also, having a Cookie or Set-Cookie header field doesn't stop HTTP caches from storing and reusing a response π§
Origin servers SHOULD NOT fold multiple Set-Cookie header fields into a single header field. Here's why: the usual folding mechanism for HTTP header fields (as defined in [RFC2616]) might change the semantics of Set-Cookie, because Set-Cookie uses the %x2C (",") character in a way that clashes with that folding π
3.1. Examples π
Using the Set-Cookie header, a server can send the user agent a short string in an HTTP response. The user agent then returns that string in future HTTP requests that are within the scope of the cookie. For example, the server can send a "session identifier" named SID with the value 31d4d96e407aad42, and the user agent returns it in later requests β¨
== Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42
The server can change the default scope of the cookie with the Path and Domain attributes. For example, the server can tell the user agent to send the cookie to every path and every subdomain of example.com π¦
== Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=example.com
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42
Next up, the server can store multiple cookies at the user agent π In this example, it stores a session identifier and the user's preferred language, using two Set-Cookie header fields. Look at the Secure and HttpOnly attributes on the session identifier: the server uses them to add extra security protections for the more sensitive value (see Section 4.1.2.) π₯
== Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly
Set-Cookie: lang=en-US; Path=/; Domain=example.com
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42; lang=en-US
Notice that the Cookie header above holds two cookies, one named SID and one named lang π If the server wants the user agent to keep a cookie across multiple "sessions" (like when the user agent restarts), it can set an expiration date with the Expires attribute. Heads up though: the user agent might delete the cookie before that date if its cookie store goes over quota, or if the user manually deletes the server's cookie π
== Server -> User Agent ==
Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42; lang=en-US
Finally, to remove a cookie, the server returns a Set-Cookie header with an expiration date in the past. The removal only works if the Path and the Domain attribute in that Set-Cookie header match the values used when the cookie was created π
== Server -> User Agent ==
Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT
== User Agent -> Server ==
Cookie: SID=31d4d96e407aad42
4. Server Requirements π
This section describes the syntax and semantics of a well-behaved profile of the Cookie and Set-Cookie headers πΈ
4.1. Set-Cookie π
The Set-Cookie HTTP response header is how servers send cookies to the user agent π
4.1.1. Syntax β¨
Informally, the Set-Cookie response header contains the header name "Set-Cookie", then a ":", then a cookie. Each cookie starts with a name-value-pair, followed by zero or more attribute-value pairs. Servers SHOULD NOT send Set-Cookie headers that fail to conform to the following grammar: π§
set-cookie-header = "Set-Cookie:" SP set-cookie-string
set-cookie-string = cookie-pair *( ";" SP cookie-av )
cookie-pair = cookie-name "=" cookie-value
cookie-name = token
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
; US-ASCII characters excluding CTLs,
; whitespace DQUOTE, comma, semicolon,
; and backslash
token = <token, defined in [RFC2616], Section 2.2>
cookie-av = expires-av / max-age-av / domain-av /
path-av / secure-av / httponly-av /
extension-av
expires-av = "Expires=" sane-cookie-date
sane-cookie-date = <rfc1123-date, defined in [RFC2616], Section 3.3.1>
max-age-av = "Max-Age=" non-zero-digit *DIGIT
; In practice, both expires-av and max-age-av
; are limited to dates representable by the
; user agent.
non-zero-digit = %x31-39
; digits 1 through 9
domain-av = "Domain=" domain-value
domain-value = <subdomain>
; defined in [RFC1034], Section 3.5, as
; enhanced by [RFC1123], Section 2.1
path-av = "Path=" path-value
path-value = <any CHAR except CTLs or ";">
secure-av = "Secure"
httponly-av = "HttpOnly"
extension-av = <any CHAR except CTLs or ";">
Heads up, some of the grammatical terms above point to documents that use different grammar notations than this one, which uses ABNF from [RFC5234] π€
The semantics of the cookie-value aren't defined by this document π
To keep things compatible with user agents, servers that want to store arbitrary data in a cookie-value SHOULD encode that data, for example using Base64 [RFC4648] π«Ά
The parts of the set-cookie-string produced by the cookie-av term are called attributes. To keep things compatible, servers SHOULD NOT produce two attributes with the same name in the same set-cookie-string. (See Section 5.3 for how user agents handle this case.) Servers SHOULD NOT include more than one Set-Cookie header field in the same response with the same cookie-name. (See Section 5.2 for how user agents handle this case.) π
If a server sends multiple responses containing Set-Cookie headers to the user agent at the same time (like when it talks to the user agent over multiple sockets), those responses create a "race condition" that can lead to unpredictable behavior π
NOTE: Some existing user agents differ in how they interpret two-digit years. To avoid compatibility issues, servers SHOULD use the rfc1123-date format, which requires a four-digit year.
NOTE: Some user agents store and process dates in cookies as 32-bit UNIX time_t values. Implementation bugs in the libraries that support time_t processing on some systems might cause such user agents to process dates after the year 2038 incorrectly. π
4.1.2. Semantics (Non-Normative) π
This section describes simplified semantics of the Set-Cookie header. They're detailed enough to be useful for understanding the most common ways servers use cookies. The full semantics are in Section 5 β¨
When the user agent receives a Set-Cookie header, it stores the cookie together with its attributes. Later, when the user agent makes an HTTP request, it includes the applicable, non-expired cookies in the Cookie header π¦
If the user agent gets a new cookie with the same cookie-name, domain-value, and path-value as a cookie it has already stored, the existing cookie is evicted and replaced with the new one. Notice that servers can delete cookies by sending the user agent a new cookie with an Expires attribute set to a value in the past π§
Unless the cookie's attributes say otherwise, the cookie is returned only to the origin server (and not, for example, to any subdomains), and it expires at the end of the current session (as defined by the user agent). User agents ignore unrecognized cookie attributes, but not the entire cookie π
4.1.2.1. The Expires Attribute π
The Expires attribute indicates the maximum lifetime of the cookie, represented as the date and time at which the cookie expires. The user agent is not required to keep the cookie until that date has passed. In fact, user agents often evict cookies due to memory pressure or privacy concerns π
4.1.2.2. The Max-Age Attribute πΈ
The Max-Age attribute indicates the maximum lifetime of the cookie, represented as the number of seconds until the cookie expires. The user agent is not required to keep the cookie for the specified duration. In fact, user agents often evict cookies due to memory pressure or privacy concerns π₯
NOTE: Some existing user agents don't support the Max-Age attribute. User agents that don't support it ignore the attribute.
If a cookie has both the Max-Age and the Expires attribute, the Max-Age attribute takes precedence and controls the expiration date of the cookie π If a cookie has neither the Max-Age nor the Expires attribute, the user agent keeps the cookie until "the current session is over" (as defined by the user agent) π
4.1.2.3. The Domain Attribute β¨
okay so the Domain attribute is how the server picks which hosts get the cookie π if it's set to "example.com", the user agent sends the cookie in the Cookie header to example.com, www.example.com, and www.corp.example.com. bestie, the little detail here is that a leading %x2E (".") is ignored even though that character isn't allowed π but a trailing %x2E (".") makes the user agent ignore the whole attribute π. And if the server leaves out Domain entirely, the cookie only goes back to the origin server π«Ά
WARNING: some existing user agents treat a missing Domain attribute as if it were there and said the current host name π so if example.com sends a Set-Cookie header without Domain, those agents will wrongly send the cookie to www.example.com too. not it π
the user agent will reject cookies unless the Domain attribute sets a scope that would include the origin server π so foo.example.com can set a cookie with Domain "example.com" or "foo.example.com" and it gets accepted π but Domain "bar.example.com" or "baz.foo.example.com" from foo.example.com? rejected, no cap π«
NOTE: for security reasons, lots of user agents are set up to reject Domain attributes that match "public suffixes" π‘οΈ so some of them will reject "com" or "co.uk". (See Section 5.3 for more information.)
4.1.2.4. The Path Attribute π¦
the scope of each cookie is limited to a set of paths, and the Path attribute controls that πΈ if the server doesn't include Path, the user agent uses the "directory" of the request-uri's path component as the default β¨ (See Section 5.1.4 for more details.)
the user agent only includes the cookie in an HTTP request when the path portion of the request-uri matches the cookie's Path attribute, or is a subdirectory of it π§ and "/" is treated as the directory separator, so that's the vibe π
ngl, Path looks like it could isolate cookies between different paths on the same host, but you cannot rely on it for security π (see Section 8).
4.1.2.5. The Secure Attribute π
the Secure attribute limits the cookie to "secure" channels, where "secure" is defined by the user agent π when a cookie has Secure, the user agent only includes it in an HTTP request if that request goes over a secure channel (typically HTTP over Transport Layer Security (TLS) [RFC2818]) π
it looks like it would protect cookies from active network attackers, but Secure only protects the cookie's confidentiality π an active network attacker can still overwrite Secure cookies from an insecure channel and mess with their integrity (see Section 8.6 for more details) π
4.1.2.6. The HttpOnly Attribute π§ββοΈ
the HttpOnly attribute limits the cookie to HTTP requests π basically it tells the user agent to leave the cookie out when it gives access to cookies through "non-HTTP" APIs, like a browser API that exposes cookies to scripts π ββοΈ
and yes, HttpOnly is independent of Secure π«Ά a cookie can have both attributes at the same time, iykyk π₯
4.2. Cookie πͺ
4.2.1. Syntax π
the user agent sends stored cookies to the origin server in the Cookie header π¬ if the server follows the requirements in Section 4.1 (and the user agent follows Section 5), the user agent will send a Cookie header that matches this grammar:
cookie-header = "Cookie:" OWS cookie-string OWS
cookie-string = cookie-pair *( ";" SP cookie-pair )
4.2.2. Semantics π·
each cookie-pair stands for one cookie the user agent has stored π¦ it has the cookie-name and cookie-value the user agent got in the Set-Cookie header.
notice that the cookie attributes are NOT sent back π in particular, the server can't tell from the Cookie header alone when a cookie expires, which hosts or paths it's valid for, or whether it was set with Secure or HttpOnly π
what individual cookies mean in the Cookie header isn't defined by this document β¨ servers are expected to give these cookies their own application-specific meaning π
even though cookies are serialized in a line in the Cookie header, servers SHOULD NOT rely on the serialization order π and if the Cookie header has two cookies with the same name (say, ones set with different Path or Domain attributes), servers SHOULD NOT rely on the order they show up in either π
5. User Agent Requirements π
this section spells out the Cookie and Set-Cookie headers in enough detail that a user agent following these requirements can interoperate with existing servers π«Ά even the ones that don't follow the well-behaved profile in Section 4 π§
a user agent could add more restrictions than these (for better security, say) π but experiments have shown that extra strictness makes it less likely the user agent will be able to work with existing servers π©
5.1. Subcomponent Algorithms π§©
this section defines some algorithms user agents use to process specific pieces of the Cookie and Set-Cookie headers π
5.1.1. Dates π
the user agent MUST use an algorithm equivalent to the one below to parse a cookie-date π the boolean flags in the algorithm (found-time, found-day-of-month, found-month, found-year) all start out "not set" β¨
- Using the grammar below, split the cookie-date into date-tokens.
cookie-date = *delimiter date-token-list *delimiter
date-token-list = date-token *( 1*delimiter date-token )
date-token = 1*non-delimiter
delimiter = %x09 / %x20-2F / %x3B-40 / %x5B-60 / %x7B-7E
non-delimiter = %x00-08 / %x0A-1F / DIGIT / ":" / ALPHA / %x7F-FF
non-digit = %x00-2F / %x3A-FF
day-of-month = 1*2DIGIT ( non-digit *OCTET )
month = ( "jan" / "feb" / "mar" / "apr" /
"may" / "jun" / "jul" / "aug" /
"sep" / "oct" / "nov" / "dec" ) *OCTET
year = 2*4DIGIT ( non-digit *OCTET )
time = hms-time ( non-digit *OCTET )
hms-time = time-field ":" time-field ":" time-field
time-field = 1*2DIGIT
- Process each date-token one at a time, in the order they show up in the cookie-date:
- If the found-time flag is not set and the token matches the time production, set the found-time flag and set the hour-value, minute-value, and second-value to the numbers the digits in the date-token stand for, in that order. Skip the remaining sub-steps and move on to the next date-token.
- If the found-day-of-month flag is not set and the date-token matches the day-of-month production, set the found-day-of-month flag and set the day-of-month-value to the number the date-token stands for. Skip the remaining sub-steps and move on to the next date-token.
- If the found-month flag is not set and the date-token matches the month production, set the found-month flag and set the month-value to the month the date-token stands for. Skip the remaining sub-steps and move on to the next date-token.
- If the found-year flag is not set and the date-token matches the year production, set the found-year flag and set the year-value to the number the date-token stands for. Skip the remaining sub-steps and move on to the next date-token.
- If the year-value is greater than or equal to 70 and less than or equal to 99, add 1900 to the year-value π§
- If the year-value is greater than or equal to 0 and less than or equal to 69, add 2000 to the year-value π§
- NOTE: some existing user agents read two-digit years differently π
- Abort these steps and fail to parse the cookie-date if any of these are true:
- at least one of the found-day-of-month, found-month, found-year, or found-time flags is not set,
- the day-of-month-value is less than 1 or greater than 31,
- the year-value is less than 1601,
- the hour-value is greater than 23,
- the minute-value is greater than 59, or
- the second-value is greater than 59.
(Note that leap seconds can't be represented in this syntax π)
- Let the parsed-cookie-date be the date whose day-of-month, month, year, hour, minute, and second (in UTC) are the day-of-month-value, the month-value, the year-value, the hour-value, the minute-value, and the second-value, in that order. If no such date exists, abort these steps and fail to parse the cookie-date.
- Return the parsed-cookie-date as the result of this algorithm π
5.1.2. Canonicalized Host Names π
a canonicalized host name is the string you get from the following algorithm π
- Turn the host name into a sequence of individual domain name labels.
- Turn each label that is not a Non-Reserved LDH (NR-LDH) label into an A-label (see Section 2.3.2.1 of [RFC5890] for the former and latter), or into a "punycode label" (a label that comes out of the "ToASCII" conversion in Section 4 of [RFC3490]), whichever is appropriate (see Section 6.3 of this specification) β¨
- Join the resulting labels back together, separated by a %x2E (".") character π¦
5.1.3. Domain Matching π§
a string domain-matches a given domain string if at least one of the following conditions holds π
- The domain string and the string are identical. (Note that both the domain string and the string will have been canonicalized to lower case at this point.)
- All of the following conditions hold:
- The domain string is a suffix of the string.
- The last character of the string that is not included in the domain string is a %x2E (".") character.
- The string is a host name (i.e., not an IP address).
5.1.4. Paths and Path-Match π€οΈ
Okay bestie, the user agent MUST use an algorithm equivalent to this one to work out the default-path of a cookie π :
- Let uri-path be the path portion of the request-uri if such a portion exists (and empty otherwise). For example, if the request-uri contains just a path (and optional query string), then the uri-path is that path (without the
%x3F ("?")character or query string), and if the request-uri contains a full absoluteURI, the uri-path is the path component of that URI. - If the uri-path is empty or if the first character of the uri-path is not a
%x2F ("/")character, output%x2F ("/")and skip the remaining steps. - If the uri-path contains no more than one
%x2F ("/")character, output%x2F ("/")and skip the remaining step. - Output the characters of the uri-path from the first character up to, but not including, the right-most
%x2F ("/").
Now the path-match part, which is so satisfying π¦. A request-path path-matches a given cookie-path if at least one of the following conditions holds:
- The cookie-path and the request-path are identical.
- The cookie-path is a prefix of the request-path, and the last character of the cookie-path is
%x2F ("/"). - The cookie-path is a prefix of the request-path, and the first character of the request-path that is not included in the cookie-path is a
%x2F ("/")character.
5.2. The Set-Cookie Header πͺ
Okay, so when a user agent gets a Set-Cookie header field in an HTTP response, the user agent MAY ignore that whole Set-Cookie header field π. For example, the user agent might wanna block responses to "third-party" requests from setting cookies (see Section 7.1). Iconic behavior, honestly.
If the user agent does not ignore the entire Set-Cookie header field, the user agent MUST parse the field-value of the Set-Cookie header field as a set-cookie-string (defined below).
NOTE: The algorithm below is more permissive than the grammar in Section 4.1. For example, the algorithm strips leading and trailing whitespace from the cookie name and value (but keeps internal whitespace), whereas the grammar in Section 4.1 forbids whitespace in these positions. User agents use this algorithm so they can interoperate with servers that do not follow the recommendations in Section 4. It's giving flexible but still responsible π«Ά.
A user agent MUST use an algorithm equivalent to the following algorithm to parse a "set-cookie-string":
- If the set-cookie-string contains a
%x3B (";")character:- The name-value-pair string consists of the characters up to, but not including, the first
%x3B (";"), and the unparsed-attributes consist of the remainder of the set-cookie-string (including the%x3B (";")in question). - Otherwise: The name-value-pair string consists of all the characters contained in the set-cookie-string, and the unparsed-attributes is the empty string.
- The name-value-pair string consists of the characters up to, but not including, the first
- If the name-value-pair string lacks a
%x3D ("=")character, ignore the set-cookie-string entirely. - The (possibly empty) name string consists of the characters up to, but not including, the first
%x3D ("=")character, and the (possibly empty) value string consists of the characters after the first%x3D ("=")character. - Remove any leading or trailing WSP characters from the name string and the value string.
- If the name string is empty, ignore the set-cookie-string entirely.
- The cookie-name is the name string, and the cookie-value is the value string.
A user agent MUST use an algorithm equivalent to the following algorithm to parse the unparsed-attributes:
- If the unparsed-attributes string is empty, skip the rest of these steps.
- Discard the first character of the unparsed-attributes (which will be a
%x3B (";")character). - If the remaining unparsed-attributes contains a
%x3B (";")character:- Consume the characters of the unparsed-attributes up to, but not including, the first
%x3B (";")character. - Otherwise: Consume the remainder of the unparsed-attributes.
- Consume the characters of the unparsed-attributes up to, but not including, the first
Let the cookie-av string be the characters consumed in this step.
- If the cookie-av string contains a
%x3D ("=")character:- The (possibly empty) attribute-name string consists of the characters up to, but not including, the first
%x3D ("=")character, and the (possibly empty) attribute-value string consists of the characters after the first%x3D ("=")character. - Otherwise: The attribute-name string consists of the entire cookie-av string, and the attribute-value string is empty.
- The (possibly empty) attribute-name string consists of the characters up to, but not including, the first
- Remove any leading or trailing WSP characters from the attribute-name string and the attribute-value string.
- Process the attribute-name and attribute-value according to the requirements in the following subsections. (Notice that attributes with unrecognized attribute-names are ignored. π)
- Return to Step 1 of this algorithm.
When the user agent finishes parsing the set-cookie-string, the user agent is said to "receive a cookie" from the request-uri with name cookie-name, value cookie-value, and attributes cookie-attribute-list. (See Section 5.3 for additional requirements triggered by receiving a cookie.) Main character moment, literally. β¨
5.2.1. The Expires Attribute π
If the attribute-name case-insensitively matches the string "Expires", the user agent MUST process the cookie-av as follows.
Let the expiry-time be the result of parsing the attribute-value as cookie-date (see Section 5.1.1).
If the attribute-value failed to parse as a cookie date, ignore the cookie-av.
If the expiry-time is later than the last date the user agent can represent, the user agent MAY replace the expiry-time with the last representable date.
If the expiry-time is earlier than the earliest date the user agent can represent, the user agent MAY replace the expiry-time with the earliest representable date.
Append an attribute to the cookie-attribute-list with an attribute-name of Expires and an attribute-value of expiry-time.
5.2.2. The Max-Age Attribute β³
If the attribute-name case-insensitively matches the string "Max-Age", the user agent MUST process the cookie-av as follows.
If the first character of the attribute-value is not a DIGIT or a "-" character, ignore the cookie-av.
If the remainder of attribute-value contains a non-DIGIT character, ignore the cookie-av.
Let delta-seconds be the attribute-value converted to an integer.
If delta-seconds is less than or equal to zero (0), let expiry-time be the earliest representable date and time. Otherwise, let the expiry-time be the current date and time plus delta-seconds seconds.
Append an attribute to the cookie-attribute-list with an attribute-name of Max-Age and an attribute-value of expiry-time.
5.2.3. The Domain Attribute π
If the attribute-name case-insensitively matches the string "Domain", the user agent MUST process the cookie-av as follows.
If the attribute-value is empty, the behavior is undefined. However, the user agent SHOULD ignore the cookie-av entirely. (Undefined behavior is giving chaos, so just skip it, bestie π ββοΈ.)
If the first character of the attribute-value string is %x2E ("."):
Let cookie-domain be the attribute-value without the leading %x2E (".") character.
Otherwise:
Let cookie-domain be the entire attribute-value.
Convert the cookie-domain to lower case.
Append an attribute to the cookie-attribute-list with an attribute-name of Domain and an attribute-value of cookie-domain.
5.2.4. The Path Attribute π£οΈ
If the attribute-name case-insensitively matches the string "Path", the user agent MUST process the cookie-av as follows.
If the attribute-value is empty or if the first character of the attribute-value is not %x2F ("/"):
Let cookie-path be the default-path.
Otherwise:
Let cookie-path be the attribute-value.
Append an attribute to the cookie-attribute-list with an attribute-name of Path and an attribute-value of cookie-path.
5.2.5. The Secure Attribute π
If the attribute-name case-insensitively matches the string "Secure", the user agent MUST append an attribute to the cookie-attribute-list with an attribute-name of Secure and an empty attribute-value. Locked in, no cap π.
5.2.6. The HttpOnly Attribute π
If the attribute-name case-insensitively matches the string "HttpOnly", the user agent MUST append an attribute to the cookie-attribute-list with an attribute-name of HttpOnly and an empty attribute-value. Iykyk, this one is the vibe π.
5.3. Storage Model β¨
okay so the user agent stores these fields about each cookie: name, value, expiry-time, domain, path, creation-time, last-access-time, persistent-flag, host-only-flag, secure-only-flag, and http-only-flag π
when the user agent "receives a cookie" from a request-uri with a cookie-name, a cookie-value, and a cookie-attribute-list, it MUST process the cookie like this π
- A user agent MAY ignore a received cookie in its entirety π for example, it might want to block cookies from "third-party" responses, or not store cookies that are over some size limit.
- Create a new cookie with the name
cookie-nameand the valuecookie-value. Set thecreation-timeand thelast-access-timeto the current date and time β° - Check the attributes:
- If the
cookie-attribute-listcontains an attribute with anattribute-nameofMax-Age:- Set the cookie's
persistent-flagto true. - Set the cookie's
expiry-timeto theattribute-valueof the last attribute in thecookie-attribute-listwith anattribute-nameofMax-Age.
- Set the cookie's
- Otherwise, if the
cookie-attribute-listcontains an attribute with anattribute-nameofExpires(and does not contain an attribute with anattribute-nameofMax-Age):- Set the cookie's
persistent-flagto true. - Set the cookie's
expiry-timeto theattribute-valueof the last attribute in thecookie-attribute-listwith anattribute-nameofExpires.
- Set the cookie's
- Otherwise:
- Set the cookie's
persistent-flagto false. - Set the cookie's
expiry-timeto the latest representable date.
- Set the cookie's
- If the
- Check the domain:
- If the
cookie-attribute-listcontains an attribute with anattribute-nameofDomain:- Let the
domain-attributebe theattribute-valueof the last attribute in thecookie-attribute-listwith anattribute-nameofDomain.
- Let the
- Otherwise:
- Let the
domain-attributebe the empty string.
- Let the
- If the
- If the user agent is configured to reject "public suffixes" and the
domain-attributeis a public suffix:- If the
domain-attributeis identical to the canonicalizedrequest-host:- Let the
domain-attributebe the empty string.
- Let the
- Otherwise:
- Ignore the cookie entirely and abort these steps.
- If the
NOTE: A "public suffix" is a domain that is controlled by a public registry, such as "com", "co.uk", and "pvt.k12.wy.us". This step is essential for preventing attacker.com from disrupting the integrity of example.com by setting a cookie with aDomainattribute of "com". Unfortunately, the set of public suffixes (also known as "registry controlled domains") changes over time. If feasible, user agents SHOULD use an up-to-date public suffix list, such as the one maintained by the Mozilla project athttp://publicsuffix.org/. π¨
- Check the domain against the request:
- If the
domain-attributeis non-empty:- If the canonicalized
request-hostdoes not domain-match thedomain-attribute:- Ignore the cookie entirely and abort these steps.
- Otherwise:
- Set the cookie's
host-only-flagto false. - Set the cookie's
domainto thedomain-attribute.
- Set the cookie's
- If the canonicalized
- Otherwise:
- Set the cookie's
host-only-flagto true. - Set the cookie's
domainto the canonicalizedrequest-host.
- Set the cookie's
- If the
- If the
cookie-attribute-listcontains an attribute with anattribute-nameofPath, set the cookie'spathto theattribute-valueof the last attribute in thecookie-attribute-listwith anattribute-nameofPath. Otherwise, set the cookie'spathto thedefault-pathof therequest-uriπ€οΈ - If the
cookie-attribute-listcontains an attribute with anattribute-nameofSecure, set the cookie'ssecure-only-flagto true. Otherwise, set the cookie'ssecure-only-flagto false. π - If the
cookie-attribute-listcontains an attribute with anattribute-nameofHttpOnly, set the cookie'shttp-only-flagto true. Otherwise, set the cookie'shttp-only-flagto false. π - If the cookie was received from a "non-HTTP" API and the cookie's
http-only-flagis set, abort these steps and ignore the cookie entirely. - If the cookie store contains a cookie with the same
name,domain, andpathas the newly created cookie:- Let
old-cookiebe the existing cookie with the samename,domain, andpathas the newly created cookie. (Notice that this algorithm maintains the invariant that there is at most one such cookie.) π§ - If the newly created cookie was received from a "non-HTTP" API and the
old-cookie'shttp-only-flagis set, abort these steps and ignore the newly created cookie entirely. - Update the
creation-timeof the newly created cookie to match thecreation-timeof theold-cookie. - Remove the
old-cookiefrom the cookie store.
- Let
- Insert the newly created cookie into the cookie store. π
A cookie is "expired" if the cookie has an expiry date in the past. π
The user agent MUST evict all expired cookies from the cookie store if, at any time, an expired cookie exists in the cookie store. no expired cookies hanging around, bestie π§Ή
At any time, the user agent MAY "remove excess cookies" from the cookie store if the number of cookies sharing a domain field exceeds some implementation-defined upper bound (such as 50 cookies). π«£
At any time, the user agent MAY "remove excess cookies" from the cookie store if the cookie store exceeds some predetermined upper bound (such as 3000 cookies). π¦
When the user agent removes excess cookies from the cookie store, the user agent MUST evict cookies in the following priority order:
- Expired cookies.
- Cookies that share a
domainfield with more than a predetermined number of other cookies. - All cookies.
If two cookies have the same removal priority, the user agent MUST evict the cookie with the earliest last-access date first. the oldest one goes first, periodt π
When "the current session is over" (as defined by the user agent), the user agent MUST remove from the cookie store all cookies with the persistent-flag set to false. session cookies get the boot when the session ends π₯
5.4. The Cookie Header β¨
the user agent includes stored cookies in the Cookie HTTP request header πͺ
When the user agent generates an HTTP request, the user agent MUST NOT attach more than one Cookie header field. just one, no doubles π
ββοΈ
A user agent MAY omit the Cookie header in its entirety. for example, it might want to block sending cookies during "third-party" requests from setting cookies (see Section 7.1). π«
If the user agent does attach a Cookie header field to an HTTP request, the user agent MUST send the cookie-string (defined below) as the value of the header field. βοΈ
The user agent MUST use an algorithm equivalent to the following algorithm to compute the "cookie-string" from a cookie store and a request-uri:
- Let
cookie-listbe the set of cookies from the cookie store that meets all of the following requirements:- Either:
- The cookie's
host-only-flagis true and the canonicalizedrequest-hostis identical to the cookie'sdomain.
- The cookie's
- Or:
- The cookie's
host-only-flagis false and the canonicalizedrequest-hostdomain-matches the cookie'sdomain.
- The cookie's
- The
request-uri's path path-matches the cookie'spath. - If the cookie's
secure-only-flagis true, then therequest-uri's scheme must denote a "secure" protocol (as defined by the user agent).
- Either:
NOTE: The notion of a "secure" protocol is not defined by this document. Typically, user agents consider a protocol secure if the protocol makes use of transport-layer security, such as SSL or TLS. For example, most user agents consider "https" to be a scheme that denotes a secure protocol. π
- If the cookie's
http-only-flagis true, then exclude the cookie if the cookie-string is being generated for a "non-HTTP" API (as defined by the user agent).
- The user agent SHOULD sort the
cookie-listin the following order:- Cookies with longer paths are listed before cookies with shorter paths.
- Among cookies that have equal-length
pathfields, cookies with earlier creation-times are listed before cookies with later creation-times.
NOTE: Not all user agents sort the cookie-list in this order, but this order reflects common practice when this document was written, and, historically, there have been servers that (erroneously) depended on this order. π
- Update the
last-access-timeof each cookie in thecookie-listto the current date and time. β±οΈ - Serialize the
cookie-listinto a cookie-string by processing each cookie in thecookie-listin order:- Output the cookie's name, the
%x3D("=") character, and the cookie's value. - If there is an unprocessed cookie in the
cookie-list, output the characters%x3Band%x20("; ").
- Output the cookie's name, the
NOTE: Despite its name, the cookie-string is actually a sequence of octets, not a sequence of characters. To convert the cookie-string (or components thereof) into a sequence of characters (e.g., for presentation to the user), the user agent might wish to try using the UTF-8 character encoding [RFC3629] to decode the octet sequence. This decoding might fail, however, because not every sequence of octets is valid UTF-8. π€
6. Implementation Considerations β¨
6.1. Limits π
Practical user agent implementations have limits on the number and size of cookies that they can store. General-use user agents SHOULD provide each of the following minimum capabilities:
- At least 4096 bytes per cookie (as measured by the sum of the length of the cookie's name, value, and attributes).
- At least 50 cookies per domain.
- At least 3000 cookies total.
Servers SHOULD use as few and as small cookies as possible to avoid reaching these implementation limits and to minimize network bandwidth due to the Cookie header being included in every request. keep your cookies lean, bestie π
Servers SHOULD gracefully degrade if the user agent fails to return one or more cookies in the Cookie header because the user agent might evict any cookie at any time on orders from the user. be ready for the cookie to vanish, it's giving unpredictable π¦
6.2. Application Programming Interfaces π§
one reason the Cookie and Set-Cookie headers use such esoteric syntax is that many platforms (both in servers and user agents) provide a string-based application programming interface (API) to cookies. that means application-layer programmers have to generate and parse the syntax used by the Cookie and Set-Cookie headers themselves, and many programmers have done it incorrectly, which caused interoperability problems π
instead of string-based APIs, platforms would be well-served by providing more semantic APIs. it is beyond the scope of this document to recommend specific API designs, but there are clear benefits to accepting an abstract "Date" object instead of a serialized date string. honestly, a real Date object is the main character here πβ¨
6.3. IDNA Dependency and Migration β¨
okay so IDNA2008 [RFC5890] is the upgrade and it supersedes IDNA2003 [RFC3490] π but the two aren't exact twins, bestie. There are differences between them, so the same domain name label can get processed differently depending on which spec it was registered under πΈ Labels from the old system are going to be floating around in the wild for a while, so there's a whole transition period π¦
Here's the game plan: user agents SHOULD implement IDNA2008 [RFC5890] π and they MAY also implement [UTS46] or [RFC5895] to make the migration smoother π§ If a user agent doesn't do IDNA2008, then it MUST implement IDNA2003 [RFC3490] π«Ά no skipping that one, periodt β¨
7. Privacy Considerations π
Cookies get a LOT of side-eye for letting servers track people π Like, a bunch of "web analytics" companies use them to spot when you come back to a site or when you wander over to a different one π Cookies aren't the only trick servers have for tracking users across HTTP requests, but they're extra effective because they stick around between user agent sessions and can be shared between hosts π
7.1. Third-Party Cookies π¦
Third-party cookies are the real menace, no cap π When a user agent renders an HTML document, it often grabs resources from other servers (think advertising networks) π Those third-party servers can use cookies to track you even if you never actually visit them directly π Say you visit a site with content from some third party, and later you visit a different site that has content from that same third party. Boom, they can connect the dots between the two sites π€
Some user agents put restrictions on how third-party cookies behave β¨ For instance, some of them refuse to send the Cookie header in third-party requests π§ Others refuse to process the Set-Cookie header in responses to third-party requests π User agents are all over the place with their third-party cookie policies, honestly it's a whole mood πΈ This document gives user agents wide latitude to experiment with third-party cookie policies that try to balance their users' privacy needs with their compatibility needs π«Ά Still, this document does NOT endorse any particular third-party cookie policy, so don't come for it π ββοΈ
Third-party cookie blocking policies often flop at their privacy goals if servers try to work around them to track people anyway π Specifically, two servers working together can usually track users without using cookies at all, by sneaking identifying info into dynamic URLs π Iconic behavior from them, not gonna lie π
7.2. User Controls π
User agents SHOULD give users a way to manage the cookies in the cookie store π For example, a user agent might let people delete all cookies received during a certain time period, or all the cookies tied to a particular domain π Plus, lots of user agents have a UI element that lets users look through the cookies stored in their cookie store π
User agents SHOULD also give users a way to disable cookies π When cookies are disabled, the user agent MUST NOT include a Cookie header in outbound HTTP requests, and the user agent MUST NOT process Set-Cookie headers in inbound HTTP responses π« Strict rules, but they're giving clarity β¨
Some user agents let users stop cookies from being stored persistently across sessions π When that's turned on, user agents MUST treat every received cookie as if the persistent-flag were set to false π«Ά Some popular browsers expose this through "private browsing" mode [Aggarwal2010] π¦
Some user agents also let users approve each individual write to the cookie store πββοΈ Real talk though, in lots of common situations these controls spam people with a ton of prompts π© Still, some privacy-conscious users find them super useful anyway π
7.3. Expiration Dates πΈ
Servers CAN set cookie expiration dates way out in the distant future, but most user agents don't actually keep cookies for decades π So instead of picking gratuitously long expiration periods, servers SHOULD promote user privacy by choosing reasonable expiration periods based on what the cookie is actually for π§ Like, a typical session identifier might reasonably expire in two weeks ποΈ Main character restraint, I love to see it β¨
8. Security Considerations π
8.1. Overview π¨
Cookies come with a whole pile of security pitfalls, bestie π This section just gives an overview of a few of the most salient issues π
Cookies really push developers to rely on ambient authority for authentication π¬ That leaves them open to stuff like cross-site request forgery [CSRF] π And when developers store session identifiers in cookies, they often end up with session fixation vulnerabilities π
Transport-layer encryption, like the kind used in HTTPS, is NOT enough to stop a network attacker from grabbing or altering a victim's cookies π± The cookie protocol itself has its own vulnerabilities (check out "Weak Confidentiality" and "Weak Integrity", below) π¦ On top of that, by default, cookies don't give you confidentiality or integrity against network attackers, even when they're paired with HTTPS π
8.2. Ambient Authority π
A server that uses cookies to authenticate users can end up with security problems because some user agents let remote parties trigger HTTP requests from the user agent (through HTTP redirects or HTML forms, for example) π³ When those requests go out, the user agent attaches cookies anyway, even if the remote party has no clue what's inside them π That could let the remote party wield authority at an unwary server π
This security concern goes by a bunch of names (cross-site request forgery, confused deputy, you name it) π But the root issue is that cookies are a form of ambient authority β¨ Cookies push server operators to split designation (in the form of URLs) from authorization (in the form of cookies) π« So the user agent might supply the authorization for a resource that an attacker designated π€ That could get the server, or its clients, to take actions the attacker picked, while looking like the user authorized them π»
Instead of leaning on cookies for authorization, server operators might want to consider entangling designation and authorization by treating URLs as capabilities π With this approach, you stop storing secrets in cookies and store them in URLs instead, so the remote entity has to supply the secret itself ποΈ It's not a panacea, but applying these principles thoughtfully can lead to much more robust security π
8.3. Clear Text π
Unless the headers are sent over a secure channel (like TLS), the information in the Cookie and Set-Cookie headers goes over the wire in the clear π±
- All sensitive information conveyed in these headers is exposed to an eavesdropper π
- A malicious intermediary could alter the headers as they travel in either direction, with unpredictable results π
- A malicious client could alter the Cookie header before transmission, with unpredictable results π
Servers SHOULD encrypt and sign the contents of cookies (using whatever format the server wants) when sending them to the user agent, even when the cookies travel over a secure channel π Still, encrypting and signing cookie contents doesn't stop an attacker from transplanting a cookie from one user agent to another, or from replaying it later π¬
On top of encrypting and signing every cookie, servers that need a higher level of security SHOULD only use the Cookie and Set-Cookie headers over a secure channel π And when cookies do travel over a secure channel, servers SHOULD set the Secure attribute (see Section 4.1.2.5) on every cookie π«Ά If a server doesn't set the Secure attribute, the protection from the secure channel becomes largely moot π©
Let's make it real. Picture a webmail server that stores a session identifier in a cookie and is usually accessed over HTTPS π§ If the server doesn't set the Secure attribute on its cookies, an active network attacker can grab any outbound HTTP request from the user agent and redirect it to the webmail server over HTTP π± Even if the webmail server isn't listening for HTTP connections, the user agent still includes the cookies in that request π The attacker can snag those cookies, replay them against the server, and read the user's email π But if the server HAD set the Secure attribute on its cookies, the user agent wouldn't have included them in the clear-text request π Lesson learned, bestie β¨
8.4. Session Identifiers πͺͺ
Instead of stuffing session info directly into a cookie (where an attacker might see it or replay it), servers commonly store a nonce (or "session identifier") in a cookie π§ When the server gets an HTTP request with a nonce, it can look up the state info tied to that cookie by using the nonce as a key π
Using session identifier cookies limits the damage an attacker can do if they learn a cookie's contents, because the nonce is only useful for interacting with the server (unlike other cookie content, which might be sensitive on its own) π‘οΈ Also, using a single nonce stops an attacker from "splicing" together cookie content from two different interactions with the server, which could make the server act weird π
Using session identifiers isn't risk-free though π¬ For example, the server SHOULD take care to avoid "session fixation" vulnerabilities π¨ A session fixation attack goes like this, in three steps π¬ First, the attacker transplants a session identifier from their own user agent to the victim's user agent πͺ Second, the victim uses that session identifier to interact with the server, possibly loading the session identifier up with their credentials or confidential info π° Third, the attacker uses the session identifier to interact with the server directly, possibly getting the user's authority or confidential info π Villain arc, no cap π
8.5. Weak Confidentiality π΅οΈββοΈ
Cookies do NOT give you isolation by port π ββοΈ If a service on one port can read a cookie, then a service on another port of the same server can read it too π Same deal for writing: if a service on one port can write a cookie, so can a service on another port of the same server βοΈ For this reason, servers SHOULD NOT both run mutually distrusting services on different ports of the same host AND use cookies to store security-sensitive information π«
Cookies also don't give you isolation by scheme π Even though they're mostly used with the http and https schemes, the cookies for a given host might also be available to other schemes, like ftp and gopher π§ This lack of scheme isolation is most obvious in non-HTTP APIs that let you access cookies (like HTML's document.cookie API) π» But it's actually baked into the requirements for processing cookies themselves too (think about retrieving a URI with the gopher scheme via HTTP) π€―
And cookies don't always give you isolation by path π€οΈ The network-level protocol won't send cookies stored for one path to another path, but some user agents expose cookies through non-HTTP APIs, like HTML's document.cookie API π Since some of those user agents (web browsers, for example) don't isolate resources received from different paths, a resource retrieved from one path might be able to access cookies stored for another path π±
8.6. Weak Integrity β¨
Okay so cookies do NOT guarantee integrity for sibling domains (or their subdomains) π¬ Take foo.example.com and bar.example.com. The foo.example.com server can set a cookie with a Domain attribute of "example.com" (possibly overwriting an existing "example.com" cookie that bar.example.com set), and the user agent will happily send that cookie along in requests to bar.example.com. Worst case? bar.example.com can't tell that cookie apart from one it set itself π And foo.example.com might be able to use that to mount an attack against bar.example.com. Not it π ββοΈ
Even though Set-Cookie has a Path attribute, Path gives you zero integrity protection, because the user agent accepts any Path attribute it's handed in a Set-Cookie header. For example, a response to a request for http://example.com/foo/bar can set a cookie with a Path of "/qux" π« So, servers SHOULD NOT both run mutually distrusting services on different paths of the same host and use cookies to store security-sensitive information.
Also, an active network attacker can inject cookies into the Cookie header sent to https://example.com/ by impersonating a response from http://example.com/ and slipping in a Set-Cookie header. The HTTPS server at example.com can't tell those cookies apart from the ones it set itself in an HTTPS response. An active network attacker might be able to use this to attack example.com, even if example.com uses HTTPS exclusively. Yikes π
Servers can partially mitigate these attacks by encrypting and signing the contents of their cookies. But cryptography doesn't fully fix it, because an attacker can replay a cookie they got from the authentic example.com server in the user's session, and the results can be unpredictable π
Last but not least, an attacker might be able to force the user agent to delete cookies by storing a huge pile of them. Once the user agent hits its storage limit, it has to evict some cookies. So, servers SHOULD NOT rely upon user agents retaining cookies. Don't count on them to hold onto your stuff π§Ί
8.7. Reliance on DNS π
Cookies rely on the Domain Name System (DNS) for security. If the DNS is partially or fully compromised, the cookie protocol might fail to provide the security properties that applications require. So DNS being shady = cookies being shady too π
9. IANA Considerations π
The permanent message header field registry (see [RFC3864]) has been updated with the following registrations. Here's the tea β
9.1. Cookie πͺ
Header field name: Cookie
Applicable protocol: http
Status: standard
Author/Change controller: IETF
Specification document: this specification (Section 5.4)
9.2. Set-Cookie πͺ
Header field name: Set-Cookie
Applicable protocol: http
Status: standard
Author/Change controller: IETF
Specification document: this specification (Section 5.2)
9.3. Cookie2 π₯
Header field name: Cookie2
Applicable protocol: http
Status: obsoleted
Author/Change controller: IETF
Specification document: [RFC2965]
9.4. Set-Cookie2 π₯
Header field name: Set-Cookie2
Applicable protocol: http
Status: obsoleted
Author/Change controller: IETF
Specification document: [RFC2965]
10. References π
10.1. Normative References π
Bestie, these are the must-read ones π«Ά
[RFC1034] Mockapetris, P., "Domain names - concepts and facilities",
STD 13, RFC 1034, November 1987.
[RFC1123] Braden, R., "Requirements for Internet Hosts - Application
and Support", STD 3, RFC 1123, October 1989.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.
[RFC3490] Faltstrom, P., Hoffman, P., and A. Costello,
"Internationalizing Domain Names in Applications (IDNA)",
RFC 3490, March 2003.
See Section 6.3 for an explanation why the normative
reference to an obsoleted specification is needed.
[RFC4790] Newman, C., Duerst, M., and A. Gulbrandsen, "Internet
Application Protocol Collation Registry", RFC 4790,
March 2007.
[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, RFC 5234, January 2008.
[RFC5890] Klensin, J., "Internationalized Domain Names for
Applications (IDNA): Definitions and Document Framework",
RFC 5890, August 2010.
[USASCII] American National Standards Institute, "Coded Character
Set -- 7-bit American Standard Code for Information
Interchange", ANSI X3.4, 1986.
10.2. Informative References π¦
These are the extra-credit reads, no pressure π
[RFC2109] Kristol, D. and L. Montulli, "HTTP State Management
Mechanism", RFC 2109, February 1997.
[RFC2965] Kristol, D. and L. Montulli, "HTTP State Management
Mechanism", RFC 2965, October 2000.
[RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000.
[Netscape] Netscape Communications Corp., "Persistent Client State --
HTTP Cookies", 1999, <http://web.archive.org/web/
20020803110822/http://wp.netscape.com/newsref/std/
cookie_spec.html>.
[Kri2001] Kristol, D., "HTTP Cookies: Standards, Privacy, and
Politics", ACM Transactions on Internet Technology Vol. 1,
#2, November 2001, <http://arxiv.org/abs/cs.SE/0105018>.
[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO
10646", STD 63, RFC 3629, November 2003.
[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data
Encodings", RFC 4648, October 2006.
[RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration
Procedures for Message Header Fields", BCP 90, RFC 3864,
September 2004.
[RFC5895] Resnick, P. and P. Hoffman, "Mapping Characters for
Internationalized Domain Names in Applications (IDNA)
2008", RFC 5895, September 2010.
[UTS46] Davis, M. and M. Suignard, "Unicode IDNA Compatibility
Processing", Unicode Technical Standards # 46, 2010,
<http://unicode.org/reports/tr46/>.
[CSRF] Barth, A., Jackson, C., and J. Mitchell, "Robust Defenses
for Cross-Site Request Forgery", 2008,
<http://portal.acm.org/citation.cfm?id=1455770.1455782>.
[Aggarwal2010]
Aggarwal, G., Burzstein, E., Jackson, C., and D. Boneh,
"An Analysis of Private Browsing Modes in Modern
Browsers", 2010, <http://www.usenix.org/events/sec10/tech/
full_papers/Aggarwal.pdf>.
Appendix A. Acknowledgements π«Ά
This document borrows heavily from RFC 2109 [RFC2109]. Huge thanks and love to David M. Kristol and Lou Montulli for their work on specifying cookies π David M. Kristol, in particular, gave invaluable advice on navigating the IETF process π We'd also like to thank Thomas Broyer, Tyler Close, Alissa Cooper, Bil Corry, corvid, Lisa Dusseault, Roy T. Fielding, Blake Frantz, Anne van Kesteren, Eran Hammer-Lahav, Jeff Hodges, Bjoern Hoehrmann, Achim Hoffmann, Georg Koppen, Dean McNamee, Alexey Melnikov, Mark Miller, Mark Pauley, Yngve N. Pettersen, Julian Reschke, Peter Saint-Andre, Mark Seaborn, Maciej Stachowiak, Daniel Stenberg, Tatsuhiro Tsujikawa, David Wagner, Dan Winship, and Dan Witte for their valuable feedback on this document πΈ
Author's Address π§
Adam Barth
University of California, Berkeley
EMail: abarth@eecs.berkeley.edu
URI: http://www.adambarth.com/
π¦ where this page comes from
- ietf: rfc6265 2011-04
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms