← Commit list

08d50a791b

Daniel Stenberg
Daniel Stenberg
2026-09-08
SUCCESS Duration: 393s

Subject

hsts: cap max-age to two years

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/hsts.c+12 -13
@@ -43,6 +43,8 @@
#define MAX_HSTS_DATELEN 17
#define UNLIMITED "unlimited"
+#define CAP_HSTS_MAX_AGE (2*365*24*3600) /* two years cap */
+
#if defined(DEBUGBUILD) || defined(UNITTESTS)
/* to play well with debug builds, we can *set* a fixed time this will
return */
@@ -257,9 +259,9 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
const char *vp = curlx_str(&val);
if(gotma)
return CURLE_BAD_FUNCTION_ARGUMENT;
- rc = curlx_str_number(&vp, &expires, TIME_T_MAX);
+ rc = curlx_str_number(&vp, &expires, CAP_HSTS_MAX_AGE);
if(rc == STRE_OVERFLOW)
- expires = CURL_OFF_T_MAX;
+ expires = CAP_HSTS_MAX_AGE;
else if(rc)
/* invalid max-age */
return CURLE_BAD_FUNCTION_ARGUMENT;
@@ -344,22 +346,21 @@ static CURLcode hsts_push(struct Curl_easy *data,
/*
* Write this single hsts entry to a single output line
*/
-static CURLcode hsts_out(struct stsentry *sts, FILE *fp)
+static void hsts_out(struct stsentry *sts, FILE *fp)
{
struct tm stamp;
if(sts->expires != TIME_T_MAX) {
CURLcode result = curlx_gmtime((time_t)sts->expires, &stamp);
- if(result)
- return result;
- curl_mfprintf(fp, "%s%s \"%d%02d%02d %02d:%02d:%02d\"\n",
- sts->includeSubDomains ? "." : "", sts->host,
- stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
- stamp.tm_hour, stamp.tm_min, stamp.tm_sec);
+ if(!result)
+ /* skip the entry if the date function fails */
+ curl_mfprintf(fp, "%s%s \"%d%02d%02d %02d:%02d:%02d\"\n",
+ sts->includeSubDomains ? "." : "", sts->host,
+ stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
+ stamp.tm_hour, stamp.tm_min, stamp.tm_sec);
}
else
curl_mfprintf(fp, "%s%s \"%s\"\n",
sts->includeSubDomains ? "." : "", sts->host, UNLIMITED);
- return CURLE_OK;
}
/*
@@ -394,9 +395,7 @@ CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
for(e = Curl_llist_head(&h->list); e; e = n) {
struct stsentry *sts = Curl_node_elem(e);
n = Curl_node_next(e);
- result = hsts_out(sts, out);
- if(result)
- break;
+ hsts_out(sts, out);
}
curlx_fclose(out);
if(!result && tempstore && curlx_rename(tempstore, file))
tests/data/Makefile.am+1 -1
@@ -1741,7 +1741,7 @@ TESTCASES = \
test1849 \
test1850 \
test1851 \
- \
+ test1862 \
test1900 \
test1901 \
test1902 \
tests/data/test1862+73 -0
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="US-ASCII"?>
+<testcase>
+<info>
+<keywords>
+HTTP
+HSTS
+</keywords>
+</info>
+
+<reply>
+
+<data crlf="headers" nocheck="yes">
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Content-Length: 6
+Connection: close
+Strict-Transport-Security: max-age=1152921504606846976
+
+-foo-
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<features>
+HSTS
+Debug
+</features>
+
+# November 11, 2030
+<setenv>
+CURL_HSTS_HTTP=yes
+CURL_TIME=1920582000
+</setenv>
+
+<name>
+HSTS with extreme max-age
+</name>
+<command>
+http://this.hsts.example:%HTTPPORT/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER --resolve this.hsts.example:%HTTPPORT:%HOSTIP
+</command>
+<file name="%LOGDIR/input%TESTNUMBER">
+# Your HSTS cache. https://curl.se/docs/hsts.html
+# This file was generated by libcurl! Edit at your own risk.
+somehere.example "20330525 03:33:20"
+elsewhere.example.com "20330727 03:33:20"
+</file>
+<disable>
+test-duphandle
+</disable>
+</client>
+
+<verify>
+# we let it CONNECT to the server to confirm HSTS but deny from there
+<protocol crlf="headers">
+GET /1862 HTTP/1.1
+Host: this.hsts.example:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+<file name="%LOGDIR/input%TESTNUMBER" mode="text">
+# Your HSTS cache. https://curl.se/docs/hsts.html
+# This file was generated by libcurl! Edit at your own risk.
+somehere.example "20330525 03:33:20"
+elsewhere.example.com "20330727 03:33:20"
+this.hsts.example "20321109 23:00:00"
+</file>
+
+</verify>
+</testcase>