Skip to content

Instantly share code, notes, and snippets.

@jamesyang124
Last active May 22, 2022 18:52
Show Gist options
  • Select an option

  • Save jamesyang124/7e81767b6248dd870c3a to your computer and use it in GitHub Desktop.

Select an option

Save jamesyang124/7e81767b6248dd870c3a to your computer and use it in GitHub Desktop.
Quick review of RFC6265 - HTTP State Management Mechanism https://tools.ietf.org/html/rfc6265

HTTP State Management Mechanism

Syntax Example

  • Origin servers SHOULD NOT fold multiple Set-Cookie header fields into a single header field. The usual mechanism for folding HTTP headers fields (i.e., as defined in [RFC2616]) might change the semantics of the Set-Cookie header field because the %x2C (",") character is used by Set-Cookie in a way that conflicts with such folding.
== 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
  • Servers SHOULD NOT include more than one Set-Cookie header field in the same response with the same cookie-name.

Syntax

set-cookie-header = "Set-Cookie:" SP set-cookie-string
set-cookie-string = cookie-pair *( ";" SP cookie-av )
cookie-pair       = cookie-name "=" cookie-value

cookie-av         = expires-av / max-age-av / domain-av / 
path-av / secure-av / httponly-av / extension-av

expires-av        = "Expires=" sane-cookie-date
max-age-av        = "Max-Age=" non-zero-digit
domain-av         = "Domain=" domain-value
path-av           = "Path=" path-value
path-value        = <any CHAR except CTLs or ";">
secure-av         = "Secure"
httponly-av       = "HttpOnly"
  • If a server sends multiple responses containing Set-Cookie headers concurrently to the user agent (e.g., when communicating with the user agent over multiple sockets), these responses create a "race condition" that can lead to unpredictable behavior.

4.1.2.1 - 4.1.2.2 Expires and Max-Age

  • If a cookie has both the Max-Age and the Expires attribute, the Max-Age attribute has precedence and controls the expiration date of the cookie. If a cookie has neither the Max-Age nor the Expires attribute, the user agent will retain the cookie until "the current session is over" (as defined by the user agent).

4.1.2.3 Domain

  • Domain attribute: Domain=example.com will only allow use agent send HTTP request include cookie in cookie header to subdomain. ex: example.com, www.corp.example.com.

  • Note that a leading %x2E ("."), if present, is ignored even though that character is not permitted, but a trailing %x2E ("."), if present, will cause the user agent to ignore the attribute.

  • If the server omits the Domain attribute, the user agent will return the cookie only to the origin server.

4.1.2.4 Path

  • The scope of each cookie is limited to a set of paths, controlled by the Path attribute. If the server omits the Path attribute, the user agent will use the "directory" of the request-uri's path component as the default value.

  • Although seemingly useful for isolating cookies between different paths within a given host, the Path attribute cannot be relied upon for security.

4.1.2.5 - 4.1.2.6 Secure and HttpOnly

  • Secure limit to HTTPS/TLS only. HttpOnly restrict that cookie cannot be access by javascript to prevent potential XSS attack.

5.1 User Agent requirment

5.1.1 Dates

    1. Abort these steps and fail to parse the cookie-date if: the year-value is less than 1601, etc.

5.1.3 Domain

  • 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 Path and Path-Match

  • The user agent MUST use an algorithm equivalent to the following algorithm to compute the default-path of a cookie:

    1. 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 1%x3F1 ("?") character or query string), and if the request-uri contains a full absoluteURI, the uri-path is the path component of that URI.
  1. 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.

  2. If the uri-path contains no more than one %x2F ("/") character (no / at all), output %x2F ("/") and skip the remaining step. ex: /folder will output as / instead.

    // request-uri:
    // https://www.nczonline.net/blog/2009/05/05/http-cookies-explained/ 
    
    document.cookie="name=Nicholas; path=/blog"
    // do path-matching, 
    // cookie Path /blog
    
    document.cookie="name=Nicholas; path=blog/"
    // rule 4, 
    // default path /blog/2009/05/05/http-cookies-explained/ 
    
    document.cookie="name3=Nicholas; path=blog"
    // rule 3 or 2, 
    // default path /blog/2009/05/05/http-cookies-explained/ 
  3. Output the characters of the uri-path from the first character up to, but not including, the right-most %x2F ("/").

  • A request-path path-matches a given cookie-path if at least one of the following conditions holds:

    1. The cookie-path and the request-path are identical.

    2. The cookie-path is a prefix of the request-path, and the last character of the cookie-path is %x2F ("/").

    Set-Cookie: name=Nicholas; path=/blog
    The path option would match /blog, /blogroll, etc.
    anything that begins with /blog is valid.

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

  • When a user agent receives a Set-Cookie header field in an HTTP response, the user agent MAY ignore the Set-Cookie header field in its entirety.

    1. If the name-value-pair string lacks a %x3D ("=") character, ignore the set-cookie-string entirely.

    2. Remove any leading or trailing WSP(white space) characters from the name string and the value string.

    3. If the name string is empty, ignore the set-cookie-string entirely.

5.2.2 The Max-Age Attribute

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

5.2.4 The Path Attribute

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

5.3 Storage Model

  • The user agent stores the following 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 the user agent MUST process the cookie as follows:

    1. A user agent MAY ignore a received cookie in its entirety.
      > For example, the user agent might wish to block receiving cookies from "third-party" responses or the user agent might not wish to store cookies that exceed some size.  
    
    1. Skip.

    2. If the cookie-attribute-list contains an attribute with an attribute-name of Max-Age:

      Set the cookie's persistent-flag to true.

    Set the cookie's expiry-time to attribute-value of the last attribute in the cookie-attribute-list with an attribute-name of Max-Age.

      If not found, then lookup `Expires` and apply same rule as above.
    
      Otherwise, set cookie as session cookie:
    

    Set the cookie's persistent-flag to false.
    Set the cookie's expiry-time to the latest representable date.

    1. If the cookie-attribute-list does not contains an attribute with an attribute-name of Domain:

      Let the domain-attribute be the empty string.

    2. If the user agent is configured to reject public suffixes and the domain-attribute is a public suffix:

      • If the domain-attribute is identical to the canonicalized request-host:

        Let the domain-attribute be the empty string.

      • Otherwise:

        Ignore the cookie entirely and abort these steps.

      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 a Domain attribute of "com".

    1. If the domain-attribute is non-empty:
    • If the canonicalized request-host does not domain-match the domain-attribute:

       > Ignore the cookie entirely and abort these steps.
      
    • Otherwise:

       > Set the cookie's host-only-flag to false.   
       > Set the cookie's domain to the domain-attribute.
      

      If the domain-attribute is empty:

      Set the cookie's host-only-flag to true.
      Set the cookie's domain to the canonicalized request-host.
      ex: www.nconline.net from reuqest to https://www.nconline.net/blogger/12345

    1. Path part, skip.

    2. If the cookie-attribute-list contains an attribute with an attribute-name of Secure, set the cookie's secure-only-flag to true. Otherwise, set to false.

    3. HttpOnly and http-only-flag apply same rule as above.

  1. If the cookie was received from a non-HTTP API and the cookie's http-only-flag is set, abort these steps and ignore the cookie entirely. ex: javascript document.cookie, or ajax API.

  2. If the cookie store contains an old cookie with the same name, domain, and path as the newly created cookie:

    1. If the newly created cookie was received from a "non-HTTP" API and the old-cookie's http-only-flag is set, abort these steps and ignore the newly created cookie entirely.

    2. Update the creation-time of the newly created cookie to match the creation-time of the old-cookie.

    3. Remove the old-cookie from the cookie store.

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

- When the user agent removes excess cookies from the cookie store, **the user agent MUST evict cookies in the following priority order** (wipe out pesistent cookie):

   1.  Expired cookies.  
 2.  Cookies that share a domain field with more than a predetermined number of other cookies.  
 3.  All cookies.  

	- If two cookies have the same removal priority, **the user agent MUST evict the cookie with the earliest `last-access` date first**.

- 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**. (wipe out session cookie)

5.4 The Cookie Header

  • Update the last-access-time of each cookie in the cookie-list to the current date and time.

  • Serialize the cookie-list into a cookie-string by processing each cookie in the cookie-list in order:

     1.  Output the cookie's name, the `%x3D` ("=") character, and the
         cookie's value.
    
     2.  If there is an unprocessed cookie in the cookie-list, output
         the characters `%x3B` and `%x20` ("; space").
    

6 Implementation Considerations

6.1 limits

  • General-use user agents SHOULD provide each of the following minimum capabilities:

    1. At least 4096 bytes per cookie (as measured by the sum of the length of the cookie's name, value, and attributes).

      Now implement as max size of cookie.

    2. At least 50 cookies per domain.

    3. At least 3000 cookies total.

7 Privacy Considerations

7.1. Third-Party Cookies

  • Particularly worrisome are so-called "third-party" cookies. In rendering an HTML document, a user agent often requests resources from other servers (such as advertising networks).

  • These third-party servers can use cookies to track the user even if the user never visits the server directly.

    For example, if a user visits a site that contains content from a third party and then later visits another site that contains content from the same third party, the third party can track the user between the two sites.

8 Security Considerations

8.2 Ambient Authority

  • A server that uses cookies to authenticate users can suffer security vulnerabilities because Some user agents let remote parties issue HTTP requests from the user agent (e.g., via HTTP redirects or HTML forms).

  • When issuing those requests, user agents attach cookies even if the remote party does not know the contents of the cookies, potentially letting the remote party exercise authority at an unwary server. (CSRF)

  • Instead of storing secrets in cookies, this approach stores secrets in URLs, requiring the remote entity to supply the secret itself. Although this approach is not a panacea, judicious application of these principles can lead to more robust security.

8.3 Clear text

  • Unless sent over a secure channel (such as TLS), the information in the Cookie and Set-Cookie headers is transmitted in the clear.

    1. All sensitive information conveyed in these headers is exposed to an eavesdropper.

    2. A malicious intermediary could alter the headers as they travel in either direction, with unpredictable results.

    3. A malicious client could alter the Cookie header before transmission, with unpredictable results.

  • Servers SHOULD encrypt and sign the contents of cookies when transmitting them to the user agent (even when sending the cookies over a secure channel) and set Secure attribute.

  • However, encrypting and signing cookie contents does not prevent an attacker from transplanting a cookie from one user agent to another or from replaying the cookie at a later time.

    Timestamp for encryption and authenticity token in HTML form submission is important!

8.4 Session Identifier

  • Instead of storing session information directly in a cookie (where it might be exposed to or replayed by an attacker), servers commonly store a nonce (or "session identifier") in a cookie. Then the server can look up state information associated with the cookie using the nonce as a key.

8.5 - 8.6 Weak Confidentiality and Weak Integrity

  • Cookie is poor for both because its clear text format.

  • Even though the Set-Cookie header supports the Path attribute, the Path attribute does not provide any integrity protection because the user agent will accept an arbitrary Path attribute in a Set-Cookie header.

    For example, an HTTP response to a request for
    http://example.com/foo/bar can set a cookie with a Path attribute of /qux.
    Consequently, servers SHOULD NOT both run mutually distrusting services on different paths of the same host and use cookies to store security-sensitive information.

  • An active network attacker(through DNS) can also inject cookies into the Cookie header sent to https://example.com/ by impersonating a response from http://example.com/ (using HTTP scheme, not HTTPS) and injecting a Set-Cookie header.

    The HTTPS server at example.com will be unable to distinguish these cookies from cookies that it set itself in an HTTPS response.

    An active network attacker might be able to leverage this ability to mount an attack against example.com even if example.com uses HTTPS exclusively.

8.7. Reliance on DNS

  • Cookies rely upon 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 required by applications. Ex: active network attacker.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment