← Commit list

4080ace060

Arham Wani
Arham Wani
2026-08-26
SUCCESS Duration: 396s

Subject

hsts: only match the exact strings

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+31 -29
@@ -223,53 +223,55 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
return CURLE_OK;
do {
- curlx_str_passblanks(&p);
- if(curl_strnequal("max-age", p, 7)) {
- bool quoted = FALSE;
- int rc;
-
- if(gotma)
- return CURLE_BAD_FUNCTION_ARGUMENT;
+ struct Curl_str word;
+ struct Curl_str val = { 0 };
+ int rc;
+ bool assign = FALSE;
- p += 7;
+ do {
curlx_str_passblanks(&p);
- if(curlx_str_single(&p, '='))
- return CURLE_BAD_FUNCTION_ARGUMENT;
+ if(*p == ';')
+ p++;
+ else
+ break;
+ } while(1);
+ if(curlx_str_cspn(&p, &word, ";=\r\n \t"))
+ break;
+
+ curlx_str_passblanks(&p);
+ if(!curlx_str_single(&p, '=')) {
+ assign = TRUE;
curlx_str_passblanks(&p);
- if(!curlx_str_single(&p, '\"'))
- quoted = TRUE;
+ if(*p == '\"') {
+ if(curlx_str_quotedword(&p, &val, MAX_HSTS_LINE))
+ break;
+ }
+ else {
+ if(curlx_str_cspn(&p, &val, ", ;\r\n"))
+ break;
+ }
+ }
- rc = curlx_str_number(&p, &expires, TIME_T_MAX);
+ if(assign && curlx_str_casecompare(&word, "max-age")) {
+ const char *vp = curlx_str(&val);
+ if(gotma)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ rc = curlx_str_number(&vp, &expires, TIME_T_MAX);
if(rc == STRE_OVERFLOW)
expires = CURL_OFF_T_MAX;
else if(rc)
/* invalid max-age */
return CURLE_BAD_FUNCTION_ARGUMENT;
- if(quoted) {
- if(*p != '\"')
- return CURLE_BAD_FUNCTION_ARGUMENT;
- p++;
- }
gotma = TRUE;
}
- else if(curl_strnequal("includesubdomains", p, 17)) {
+ else if(curlx_str_casecompare(&word, "includesubdomains")) {
if(gotinc)
return CURLE_BAD_FUNCTION_ARGUMENT;
subdomains = TRUE;
- p += 17;
gotinc = TRUE;
}
- else {
- /* unknown directive, do a lame attempt to skip */
- while(*p && (*p != ';'))
- p++;
- }
-
- curlx_str_passblanks(&p);
- if(*p == ';')
- p++;
} while(*p);
if(!gotma)
tests/unit/unit1660.c+17 -0
@@ -142,6 +142,23 @@ static CURLcode test_unit1660(const char *arg)
showsts(e, chost);
}
+ result = Curl_hsts_parse(h, "prefix.example",
+ "max-age=60; includeSubDomainsExtra");
+ fail_if(result, "failed to parse unknown HSTS directive");
+ e = hsts_check(h, "child.prefix.example",
+ strlen("child.prefix.example"), TRUE);
+ fail_if(e, "unknown directive enabled subdomain matching");
+ result = Curl_hsts_parse(h, "prefix.example", "max-age=0");
+ fail_if(result, "failed to remove HSTS test entry");
+
+ result = Curl_hsts_parse(h, "unknown.example",
+ "max-age-extra=1; max-age=60");
+ fail_if(result, "failed to ignore unknown HSTS directive");
+ e = hsts_check(h, "unknown.example", strlen("unknown.example"), FALSE);
+ fail_if(!e, "recognized directive after unknown directive was ignored");
+ result = Curl_hsts_parse(h, "unknown.example", "max-age=0");
+ fail_if(result, "failed to remove HSTS test entry");
+
curl_mprintf("Number of entries: %zu\n", Curl_llist_count(&h->list));
/* verify that it is exists for 7 seconds */