✓ProveIt
Examples / Report #1557449 Saved analysis

CVE-2022-30115: HSTS bypass via trailing dot

curl · 2022-05-0312.8s analysis · $0.013 in model calls

What the report claims

A trailing dot in a hostname bypasses HSTS enforcement, allowing HTTP URLs to be treated as HTTPS and causing a downgrade to HTTP after a redirect.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2022-30115 HSTS bypass via trailing dot

Shown for comparison after analysis. The pipeline did not see this label.

ProveIt's finding

Needs human review

The available evidence does not settle the report. A maintainer should investigate.

Why this finding?
  • The provided curl source (lib/urldata.h) contains only type definitions and does not include the HSTS implementation (cache loading, hostname lookup, protocol upgrade logic).
  • Deterministic checks returned 'nothing_to_check', meaning the automated grounding could not locate the relevant HSTS code in the revision (0d015fb3f6f4, master on 2022-05-03).
  • The trailing-dot bypass is a known vulnerability class in other HTTP clients (Chromium, Mozilla, Wget per external sources E1, E3), making the report plausible, but curl's specific code is absent from the evidence.
  • Without the HSTS cache lookup and hostname comparison code, none of the claims can be verified or contradicted.
What still needs checking
  • The HSTS implementation files (e.g., lib/hsts.c, lib/hsts.h, or wherever CURLOPT_HSTS is handled and the cache is consulted).
  • The hostname normalization or comparison function used during HSTS cache lookup.
  • Confirmation of whether HSTS support existed in curl at the target revision (2022-05-03).
How this analysis ran 4 claims · 0 citations verified

Checked against curl master on 2022-05-03 (0d015fb3f6f4). Test evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.

1 · Grounding
nothing to check
no model · 0 references checked out, 0 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
4 claims · 1339 tokens · $0.0002
3 · Evidence
1 code snippets
real curl source at 0d015fb3f6f4 · 6 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
7847 tokens · 10.7s · $0.0125
5 · Receipts
0 of 0 citations verified
every citation must point at code the judge was shown
Review a draft reply to the reporter

Edit and verify before sending.

Thank you for the report. The provided code snippets do not include curl's HSTS implementation (cache loading, hostname lookup, or protocol upgrade logic), so we cannot verify the trailing-dot bypass claim. Could you indicate which source files implement CURLOPT_HSTS and the HSTS cache check? If you have a patch or know the function names, that would help us triage quickly.

Inspect all claims and source code 4 claims · 1 code excerpts

Report claims

C1flaw not verifiable

A trailing dot in the hostname bypasses HSTS check

Read the reasoning

The claim that a trailing dot bypasses the HSTS check requires examining the HSTS cache lookup and hostname comparison logic. The provided source code only shows lib/urldata.h (type definitions), which does not contain the HSTS implementation. The deterministic checks returned 'nothing_to_check', indicating the relevant HSTS code was not found or not provided. Without the HSTS lookup code (likely in a file like lib/hsts.c or similar), this claim cannot be verified or contradicted.

C2trigger not verifiable

Using a URL with a trailing dot after loading HSTS cache from hsts.txt

Read the reasoning

The trigger describes using a URL with a trailing dot after loading an HSTS cache. This requires the URL parsing code, the --hsts option handling, and the HSTS cache loading logic. None of this code is present in the provided source snippet (lib/urldata.h lines 122-199). The deterministic checks found nothing to check, so the code path cannot be evaluated.

C3impact not verifiable

The request is sent over HTTP instead of HTTPS after a redirect

Read the reasoning

The impact claim (request sent over HTTP instead of HTTPS after a redirect) depends on the protocol upgrade logic that consults the HSTS cache. This code is not in the provided source. The external sources (E1-E6) discuss trailing-dot fixes in Wget and browser HSTS preload lists, but do not describe curl's implementation. Without curl's HSTS enforcement code, the claim cannot be decided.

C4reproduction not verifiable

curl --hsts hsts.txt http://accounts.google.com.

Read the reasoning

The reproduction command references CURLOPT_HSTS and CURLOPT_URL option handling and the HSTS cache file format. The provided source does not include the option parsing for --hsts, the HSTS file parser, or the hostname normalization (if any) applied before cache lookup. The deterministic checks found no relevant code to ground this reproduction.

Read the original report

Full report on HackerOne ↗

curl allows users to load a HSTS cache which will cause curl to use HTTPS instead of HTTP given a HTTP URL for a given site specified in the HSTS cache. If the trailing dot is used, the HSTS check will be bypassed. If a user has a preloaded hsts.txt: `````` # Your HSTS cache. https://curl.se/docs/hsts.html # This file was generated by libcurl! Edit at your own risk. accounts.google.com "20230503 08:47:52" `````` Doing the following: `````` curl --hsts hsts.txt http://accounts.google.com. `````` Will cause accounts.google.com to be loaded over HTTP `````` <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>301 Moved</TITLE></HEAD><BODY> <H1>301 Moved</H1> The document has moved <A HREF="http://accounts.google.com/">here</A>. </BODY></HTML> `````` This issue has been raised in other HTTP clients before such as in https://bugs.chromium.org/p/chromium/issues/detail?id=461481 and https://www.mozilla.org/en-US/security/advisories/mfsa2015-13/ ## Impact HSTS bypass

Source code

lib/urldata.hlines 122–199 · definition of CURLcode
122typedef CURLcode (*Curl_datastream)(struct Curl_easy *data,
123 struct connectdata *conn,
124 int *didwhat,
125 bool *done,
126 int select_res);
127#endif
128
129#include "mime.h"
130#include "imap.h"
131#include "pop3.h"
132#include "smtp.h"
133#include "ftp.h"
134#include "file.h"
135#include "vssh/ssh.h"
136#include "http.h"
137#include "rtsp.h"
138#include "smb.h"
139#include "mqtt.h"
140#include "wildcard.h"
141#include "multihandle.h"
142#include "quic.h"
143#include "c-hyper.h"
144
145#ifdef HAVE_GSSAPI
146# ifdef HAVE_GSSGNU
147# include <gss.h>
148# elif defined HAVE_GSSAPI_GSSAPI_H
149# include <gssapi/gssapi.h>
150# else
151# include <gssapi.h>
152# endif
153# ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
154# include <gssapi/gssapi_generic.h>
155# endif
156#endif
157
158#ifdef HAVE_LIBSSH2_H
159#include <libssh2.h>
160#include <libssh2_sftp.h>
161#endif /* HAVE_LIBSSH2_H */
162
163#define READBUFFER_SIZE CURL_MAX_WRITE_SIZE
164#define READBUFFER_MAX CURL_MAX_READ_SIZE
165#define READBUFFER_MIN 1024
166
167/* The default upload buffer size, should not be smaller than
168 CURL_MAX_WRITE_SIZE, as it needs to hold a full buffer as could be sent in
169 a write callback.
170
171 The size was 16KB for many years but was bumped to 64KB because it makes
172 libcurl able to do significantly faster uploads in some circumstances. Even
173 larger buffers can help further, but this is deemed a fair memory/speed
174 compromise. */
175#define UPLOADBUFFER_DEFAULT 65536
176#define UPLOADBUFFER_MAX (2*1024*1024)
177#define UPLOADBUFFER_MIN CURL_MAX_WRITE_SIZE
178
179#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU
180#define GOOD_EASY_HANDLE(x) \
181 ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
182
183/* the type we use for storing a single boolean bit */
184#ifdef _MSC_VER
185typedef bool bit;
186#define BIT(x) bool x
187#else
188typedef unsigned int bit;
189#define BIT(x) bit x:1
190#endif
191
192#ifdef HAVE_GSSAPI
193/* Types needed for krb5-ftp connections */
194struct krb5buffer {
195 void *data;
196 size_t size;
197 size_t index;
198 BIT(eof_flag);
199};