cookie: parse only the exact expire date

The date parser function is very forgiving and skips most "irrelevant"
characters in its hunt for a date to figure out. Therefore it is
important to make sure the date string is properly null terminated so
that it does not accidentally parse a piece of whatever text follows
after the date.

Add test483: test (overly) long expire dates in cookies

Closes #15709
This commit is contained in:
Daniel Stenberg 2024-12-10 12:39:57 +01:00
parent 75f0835513
commit a8c852b9a5
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 78 additions and 3 deletions

View File

@ -469,6 +469,13 @@ static int invalid_octets(const char *p)
#define CERR_PSL 14 /* a public suffix */
#define CERR_LIVE_WINS 15
/* The maximum length we accept a date string for the 'expire' keyword. The
standard date formats are within the 30 bytes range. This adds an extra
margin just to make sure it realistically works with what is used out
there.
*/
#define MAX_DATE_LENGTH 80
static int
parse_cookie_header(struct Curl_easy *data,
struct Cookie *co,
@ -709,14 +716,17 @@ parse_cookie_header(struct Curl_easy *data,
}
}
else if((nlen == 7) && strncasecompare("expires", namep, 7)) {
if(!co->expires) {
if(!co->expires && (vlen < MAX_DATE_LENGTH)) {
/*
* Let max-age have priority.
*
* If the date cannot get parsed for whatever reason, the cookie
* will be treated as a session cookie
*/
co->expires = Curl_getdate_capped(valuep);
char dbuf[MAX_DATE_LENGTH + 1];
memcpy(dbuf, valuep, vlen);
dbuf[vlen] = 0;
co->expires = Curl_getdate_capped(dbuf);
/*
* Session cookies have expires set to 0 so if we get that back

View File

@ -78,7 +78,7 @@ test444 test445 test446 test447 test448 test449 test450 test451 test452 \
test453 test454 test455 test456 test457 test458 test459 test460 test461 \
test462 test463 test467 test468 test469 test470 test471 test472 test473 \
test474 test475 test476 test477 test478 test479 test480 test481 test482 \
\
test483 \
test490 test491 test492 test493 test494 test495 test496 test497 test498 \
test499 test500 test501 test502 test503 test504 test505 test506 test507 \
test508 test509 test510 test511 test512 test513 test514 test515 test516 \

65
tests/data/test483 Normal file
View File

@ -0,0 +1,65 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
cookies
</keywords>
</info>
#
# Server-side
<reply>
<data crlf="yes">
HTTP/1.1 200 OK
Set-Cookie: name=value; expires=Fri Feb 13 11:56:27 GMT 2132
Set-Cookie: name2=value; expires=Fri Feb 13 11:56:27 ; 2132
Set-Cookie: name3=value; expires=Fri Feb 13 11:56:27 ...................................................GMT 2132
Set-Cookie: name4=value; expires=Fri Feb 13 11:56:27 ....................................................GMT 2132
Accept-Ranges: bytes
Content-Length: 6
Connection: close
-foo-
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
large-time
</features>
<name>
HTTP cookies with long expire dates
</name>
<command>
http://%HOSTIP:%HTTPPORT/%TESTNUMBER -c %LOGDIR/c%TESTNUMBER
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol crlf="yes">
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="%LOGDIR/c%TESTNUMBER" mode="text">
# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
127.0.0.1 FALSE / FALSE 0 name4 value
127.0.0.1 FALSE / FALSE 5115959787 name3 value
127.0.0.1 FALSE / FALSE 0 name2 value
127.0.0.1 FALSE / FALSE 5115959787 name value
</file>
</verify>
</testcase>