aboutsummaryrefslogtreecommitdiff
path: root/lib/cookie.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2017-09-18 00:55:07 +0200
committerDaniel Stenberg <daniel@haxx.se>2017-09-18 22:55:50 +0200
commit2bc230de63bd7da197280a69d84972b61455cd18 (patch)
treeb616832f6cd1138851d1ed87ba68fb60e0a5c85f /lib/cookie.c
parent1a072796d390a7f56739d48a5158c250e211e2f7 (diff)
cookies: reject oversized cookies
... instead of truncating them. There's no fixed limit for acceptable cookie names in RFC 6265, but the entire cookie is said to be less than 4096 bytes (section 6.1). This is also what browsers seem to implement. We now allow max 5000 bytes cookie header. Max 4095 bytes length per cookie name and value. Name + value together may not exceed 4096 bytes. Added test 1151 to verify Bug: https://curl.haxx.se/mail/lib-2017-09/0062.html Reported-by: Kevin Smith Closes #1894
Diffstat (limited to 'lib/cookie.c')
-rw-r--r--lib/cookie.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/lib/cookie.c b/lib/cookie.c
index 14defe883..1231882ed 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -375,7 +375,6 @@ Curl_cookie_add(struct Curl_easy *data,
unless set */
{
struct Cookie *clist;
- char name[MAX_NAME];
struct Cookie *co;
struct Cookie *lastc = NULL;
time_t now = time(NULL);
@@ -397,12 +396,14 @@ Curl_cookie_add(struct Curl_easy *data,
if(httpheader) {
/* This line was read off a HTTP-header */
+ char name[MAX_NAME];
+ char what[MAX_NAME];
const char *ptr;
const char *semiptr;
- char *what;
- what = malloc(MAX_COOKIE_LINE);
- if(!what) {
+ size_t linelength = strlen(lineptr);
+ if(linelength > MAX_COOKIE_LINE) {
+ /* discard overly long lines at once */
free(co);
return NULL;
}
@@ -417,7 +418,7 @@ Curl_cookie_add(struct Curl_easy *data,
/* we have a <what>=<this> pair or a stand-alone word here */
name[0] = what[0] = 0; /* init the buffers */
if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n=] =%"
- MAX_COOKIE_LINE_TXT "[^;\r\n]",
+ MAX_NAME_TXT "[^;\r\n]",
name, what)) {
/* Use strstore() below to properly deal with received cookie
headers that have the same string property set more than once,
@@ -429,6 +430,20 @@ Curl_cookie_add(struct Curl_easy *data,
size_t nlen = strlen(name);
const char *endofn = &ptr[ nlen ];
+ infof(data, "cookie size: name/val %d + %d bytes\n",
+ nlen, len);
+
+ if(nlen >= (MAX_NAME-1) || len >= (MAX_NAME-1) ||
+ ((nlen + len) > MAX_NAME)) {
+ /* too long individual name or contents, or too long combination of
+ name + contents. Chrome and Firefox support 4095 or 4096 bytes
+ combo. */
+ free(co);
+ infof(data, "oversized cookie dropped, name/val %d + %d bytes\n",
+ nlen, len);
+ return NULL;
+ }
+
/* name ends with a '=' ? */
sep = (*endofn == '=')?TRUE:FALSE;
@@ -659,8 +674,6 @@ Curl_cookie_add(struct Curl_easy *data,
}
}
- free(what);
-
if(badcookie || !co->name) {
/* we didn't get a cookie name or a bad one,
this is an illegal line, bail out */