| From 8313ef3f507b5bdc54e985cae71aa9df00609d55 Mon Sep 17 00:00:00 2001 |
| From: Daniel Stenberg <daniel@haxx.se> |
| Date: Mon, 9 May 2022 08:13:55 +0200 |
| Subject: [PATCH] hsts: ignore trailing dots when comparing hosts names |
| |
| CVE-2022-30115 |
| |
| Reported-by: Axel Chong |
| Bug: https://curl.se/docs/CVE-2022-30115.html |
| Closes #8821 |
| |
| Upstream-Status: Backport [https://github.com/curl/curl/commit/fae6fea209a2d4db1582f608bd8cc8000721733a] |
| Signed-off-by: Robert Joslyn <robert.joslyn@redrectangle.org> |
| --- |
| lib/hsts.c | 30 +++++++++++++++++++++++++----- |
| 1 file changed, 25 insertions(+), 5 deletions(-) |
| |
| diff --git a/lib/hsts.c b/lib/hsts.c |
| index 03fcc9e..b9fa6f7 100644 |
| --- a/lib/hsts.c |
| +++ b/lib/hsts.c |
| @@ -114,16 +114,25 @@ static CURLcode hsts_create(struct hsts *h, |
| curl_off_t expires) |
| { |
| struct stsentry *sts = hsts_entry(); |
| + char *duphost; |
| + size_t hlen; |
| if(!sts) |
| return CURLE_OUT_OF_MEMORY; |
| |
| - sts->expires = expires; |
| - sts->includeSubDomains = subdomains; |
| - sts->host = strdup(hostname); |
| - if(!sts->host) { |
| + duphost = strdup(hostname); |
| + if(!duphost) { |
| free(sts); |
| return CURLE_OUT_OF_MEMORY; |
| } |
| + |
| + hlen = strlen(duphost); |
| + if(duphost[hlen - 1] == '.') |
| + /* strip off trailing any dot */ |
| + duphost[--hlen] = 0; |
| + |
| + sts->host = duphost; |
| + sts->expires = expires; |
| + sts->includeSubDomains = subdomains; |
| Curl_llist_insert_next(&h->list, h->list.tail, sts, &sts->node); |
| return CURLE_OK; |
| } |
| @@ -238,10 +247,21 @@ struct stsentry *Curl_hsts(struct hsts *h, const char *hostname, |
| bool subdomain) |
| { |
| if(h) { |
| + char buffer[MAX_HSTS_HOSTLEN + 1]; |
| time_t now = time(NULL); |
| size_t hlen = strlen(hostname); |
| struct Curl_llist_element *e; |
| struct Curl_llist_element *n; |
| + |
| + if((hlen > MAX_HSTS_HOSTLEN) || !hlen) |
| + return NULL; |
| + memcpy(buffer, hostname, hlen); |
| + if(hostname[hlen-1] == '.') |
| + /* remove the trailing dot */ |
| + --hlen; |
| + buffer[hlen] = 0; |
| + hostname = buffer; |
| + |
| for(e = h->list.head; e; e = n) { |
| struct stsentry *sts = e->ptr; |
| n = e->next; |
| @@ -440,7 +460,7 @@ static CURLcode hsts_pull(struct Curl_easy *data, struct hsts *h) |
| CURLSTScode sc; |
| DEBUGASSERT(h); |
| do { |
| - char buffer[257]; |
| + char buffer[MAX_HSTS_HOSTLEN + 1]; |
| struct curl_hstsentry e; |
| e.name = buffer; |
| e.namelen = sizeof(buffer)-1; |