1
0
mirror of https://github.com/moparisthebest/curl synced 2024-11-11 20:15:03 -05:00

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>
This commit is contained in:
Daniel Gustafsson 2019-02-17 00:09:30 +01:00
parent 0299b262cd
commit e6522522f9
5 changed files with 76 additions and 13 deletions

View File

@ -18,9 +18,16 @@
original [Netscape spec from 1994](https://curl.haxx.se/rfc/cookie_spec.html). 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 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) [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 ## Cookies saved to disk

View File

@ -10,16 +10,6 @@ QUIC
See the [QUIC wiki page](https://github.com/curl/curl/wiki/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 SRV records
----------- -----------

View File

@ -528,6 +528,19 @@ Curl_cookie_add(struct Curl_easy *data,
while(*whatptr && ISBLANK(*whatptr)) while(*whatptr && ISBLANK(*whatptr))
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) { if(!co->name) {
/* The very first name/value pair is the actual cookie name */ /* The very first name/value pair is the actual cookie name */
if(!sep) { if(!sep) {
@ -862,6 +875,11 @@ Curl_cookie_add(struct Curl_easy *data,
co->name = strdup(ptr); co->name = strdup(ptr);
if(!co->name) if(!co->name)
badcookie = TRUE; 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; break;
case 6: case 6:
co->value = strdup(ptr); 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 */ if(!c->running && /* read from a file */
c->newsession && /* clean session cookies */ c->newsession && /* clean session cookies */
!co->expires) { /* this is a session cookie since it doesn't expire! */ !co->expires) { /* this is a session cookie since it doesn't expire! */

View File

@ -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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * 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 livecookie; /* updated from a server, not a stored file */
bool httponly; /* true if the httponly directive is present */ bool httponly; /* true if the httponly directive is present */
int creationtime; /* time when the cookie was written */ 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 #define COOKIE_HASH_SIZE 256
struct CookieInfo { struct CookieInfo {

View File

@ -18,6 +18,15 @@ Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake Server: test-server/fake
Set-Cookie: super=secret; domain=example.com; path=/1561; secure; Set-Cookie: super=secret; domain=example.com; path=/1561; secure;
Set-Cookie: supersuper=secret; domain=example.com; path=/1561/login/; 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 Content-Length: 7
nomnom 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/en;
Set-Cookie: supersuper=secret; domain=example.com; path=/1561/login; Set-Cookie: supersuper=secret; domain=example.com; path=/1561/login;
Set-Cookie: secureoverhttp=yes; domain=example.com; path=/1561; secure; 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 Content-Length: 7
nomnom nomnom
@ -77,6 +94,9 @@ Accept: */*
# This file was generated by libcurl! Edit at your own risk. # This file was generated by libcurl! Edit at your own risk.
.example.com TRUE /foo FALSE 0 public yes .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 .example.com TRUE /1561/login/ TRUE 0 supersuper secret
#HttpOnly_.example.com TRUE /15 FALSE 0 super secret #HttpOnly_.example.com TRUE /15 FALSE 0 super secret
</file> </file>