]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
cookie: parse only the exact expire date
authorDaniel Stenberg <daniel@haxx.se>
Tue, 10 Dec 2024 11:39:57 +0000 (12:39 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 11 Dec 2024 08:31:53 +0000 (09:31 +0100)
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

lib/cookie.c
tests/data/Makefile.am
tests/data/test483 [new file with mode: 0644]

index 773e5357d3e2712d182136d79025ec94e46e2e78..aaa65368cfc76da51d946e9b40e8a5f78de01b9a 100644 (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
index 776b5934bb99270ebb07acb8db618370f1fa9ac2..8e2c31863a151ded1c43bf29beb898508be5bf8e 100644 (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 \
diff --git a/tests/data/test483 b/tests/data/test483
new file mode 100644 (file)
index 0000000..6f4e482
--- /dev/null
@@ -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\r
+Set-Cookie: name2=value; expires=Fri Feb 13 11:56:27 ; 2132\r
+Set-Cookie: name3=value; expires=Fri Feb 13 11:56:27 ...................................................GMT 2132\r
+Set-Cookie: name4=value; expires=Fri Feb 13 11:56:27 ....................................................GMT 2132\r
+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>