Permalink
Browse files

cookie: Add support for cookie prefixes

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

Closes #xxxx
  • Loading branch information...
danielgustafsson committed Feb 11, 2019
1 parent 3f16990 commit dd8f9dfcb9ad2f092655148206b9911378539482
Showing with 73 additions and 13 deletions.
  1. +6 −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,13 @@
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).
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 are 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-cookie-prefixes-00
*/
#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 dd8f9df

Please sign in to comment.