Skip to content
Permalink
Browse files

cookie: Add support for cookie prefixes

The draft-ietf-httpbis-rfc6265bis-02 draft, specify a set of prefixes
and how they should affect cookie initialization, which has been
adopted by the major browsers. This adds support for the two prefixes
defined, __Host- and __Secure, and updates the testcase with the
supplied examples from the draft.

Closes #3554
Reviewed-by: Daniel Stenberg <daniel@haxx.se>
  • Loading branch information...
danielgustafsson committed Feb 16, 2019
1 parent 0299b26 commit e6522522f96ad96b459e608c6cdcd46a32099b5b
Showing with 76 additions and 13 deletions.
  1. +9 −2 docs/HTTP-COOKIES.md
  2. +0 −10 docs/ROADMAP.md
  3. +38 −0 lib/cookie.c
  4. +9 −1 lib/cookie.h
  5. +20 −0 tests/data/test1561
@@ -18,9 +18,16 @@
original [Netscape spec from 1994](https://curl.haxx.se/rfc/cookie_spec.html).

In 2011, [RFC6265](https://www.ietf.org/rfc/rfc6265.txt) was finally
published and details how cookies work within HTTP. In 2017, an update was
published and details how cookies work within HTTP. In 2016, an update which
added support for prefixes was
[proposed](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00),
and in 2017, another update was
[drafted](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone-01)
to deprecate modification of 'secure' cookies from non-secure origins.
to deprecate modification of 'secure' cookies from non-secure origins. Both
of these drafs have been incorporated into a proposal to
[replace](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-02)
RFC6265. Cookie prefixes and secure cookie modification protection has been
implemented by curl.

## Cookies saved to disk

@@ -10,16 +10,6 @@ QUIC

See the [QUIC wiki page](https://github.com/curl/curl/wiki/QUIC).

HTTP cookies
------------

On top of what we already support, the prefix cookie draft has been adopted by
the httpwg in IETF and we should support it as the popular browsers will:

[Cookie Prefixes](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00)

[Firefox bug report about secure cookies](https://bugzilla.mozilla.org/show_bug.cgi?id=976073)

SRV records
-----------

@@ -528,6 +528,19 @@ Curl_cookie_add(struct Curl_easy *data,
while(*whatptr && ISBLANK(*whatptr))
whatptr++;

/*
* Check if we have a reserved prefix set before anything else, as we
* otherwise have to test for the prefix in both the cookie name and
* "the rest". Prefixes must start with '__' and end with a '-', so
* only test for names where that can possibly be true.
*/
if(nlen > 3 && name[0] == '_' && name[1] == '_') {
if(strncasecompare("__Secure-", name, 9))
co->prefix |= COOKIE_PREFIX__SECURE;
else if(strncasecompare("__Host-", name, 7))
co->prefix |= COOKIE_PREFIX__HOST;
}

if(!co->name) {
/* The very first name/value pair is the actual cookie name */
if(!sep) {
@@ -862,6 +875,11 @@ Curl_cookie_add(struct Curl_easy *data,
co->name = strdup(ptr);
if(!co->name)
badcookie = TRUE;
/* For Netscape file format cookies we check prefix on the name */
if(strncasecompare("__Secure-", co->name, 9))
co->prefix |= COOKIE_PREFIX__SECURE;
else if(strncasecompare("__Host-", co->name, 7))
co->prefix |= COOKIE_PREFIX__HOST;
break;
case 6:
co->value = strdup(ptr);
@@ -890,6 +908,26 @@ Curl_cookie_add(struct Curl_easy *data,

}

if(co->prefix & COOKIE_PREFIX__SECURE) {
/* The __Secure- prefix only requires that the cookie be set secure */
if(!co->secure) {
freecookie(co);
return NULL;
}
}
if(co->prefix & COOKIE_PREFIX__HOST) {
/*
* The __Host- prefix requires the cookie to be secure, have a "/" path
* and not have a domain set.
*/
if(co->secure && co->path && strcmp(co->path, "/") == 0 && !co->tailmatch)
;
else {
freecookie(co);
return NULL;
}
}

if(!c->running && /* read from a file */
c->newsession && /* clean session cookies */
!co->expires) { /* this is a session cookie since it doesn't expire! */
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -44,8 +44,16 @@ struct Cookie {
bool livecookie; /* updated from a server, not a stored file */
bool httponly; /* true if the httponly directive is present */
int creationtime; /* time when the cookie was written */
unsigned char prefix; /* bitmap fields indicating which prefix are set */
};

/*
* Available cookie prefixes, as defined in
* draft-ietf-httpbis-rfc6265bis-02
*/
#define COOKIE_PREFIX__SECURE (1<<0)
#define COOKIE_PREFIX__HOST (1<<1)

#define COOKIE_HASH_SIZE 256

struct CookieInfo {
@@ -18,6 +18,15 @@ Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Set-Cookie: super=secret; domain=example.com; path=/1561; secure;
Set-Cookie: supersuper=secret; domain=example.com; path=/1561/login/; secure;
Set-Cookie: __Secure-SID=12345; Domain=example.com
Set-Cookie: __Secure-SID=12346; Secure; Domain=example.com
Set-Cookie: supersupersuper=secret; __Secure-SID=12346; Secure; Domain=example.com
Set-Cookie: __Host-SID=22345
Set-Cookie: __Host-SID=22346; Secure
Set-Cookie: __Host-SID=22347; Domain=example.com
Set-Cookie: __Host-SID=22348; Domain=example.com; Path=/
Set-Cookie: __Host-SID=22349; Secure; Domain=example.com; Path=/
Set-Cookie: __Host-SID=12346; Secure; Path=/
Content-Length: 7

nomnom
@@ -33,6 +42,14 @@ Set-Cookie: public=yes; domain=example.com; path=/foo;
Set-Cookie: supersuper=secret; domain=example.com; path=/1561/login/en;
Set-Cookie: supersuper=secret; domain=example.com; path=/1561/login;
Set-Cookie: secureoverhttp=yes; domain=example.com; path=/1561; secure;
Set-Cookie: __Secure-SID=22345; Domain=example.com
Set-Cookie: __Secure-SID=22346; Secure; Domain=example.com
Set-Cookie: __Host-SID=32345
Set-Cookie: __Host-SID=32346; Secure
Set-Cookie: __Host-SID=32347; Domain=example.com
Set-Cookie: __Host-SID=32348; Domain=example.com; Path=/
Set-Cookie: __Host-SID=32349; Secure; Domain=example.com; Path=/
Set-Cookie: __Host-SID=32350; Secure; Path=/
Content-Length: 7

nomnom
@@ -77,6 +94,9 @@ Accept: */*
# This file was generated by libcurl! Edit at your own risk.

.example.com TRUE /foo FALSE 0 public yes
www.example.com FALSE / TRUE 0 __Host-SID 12346
.example.com TRUE / TRUE 0 supersupersuper secret
.example.com TRUE / TRUE 0 __Secure-SID 12346
.example.com TRUE /1561/login/ TRUE 0 supersuper secret
#HttpOnly_.example.com TRUE /15 FALSE 0 super secret
</file>

0 comments on commit e652252

Please sign in to comment.
You can’t perform that action at this time.