✓ProveIt
Examples / Report #1223565 Saved analysis

CVE-2021-22924: Bad connection reuse due to flawed path name checks

curl · 2021-06-1117.7s analysis · $0.016 in model calls

What the report claims

Bad connection reuse due to flawed path name checks in curl's SSL config matching function

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2021-22924 Bad connection reuse due to flawed path name checks

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.

Judgment withdrawn. The answer failed the evidence check.
See the withdrawn model reasoning

The following reasoning failed the citation check and does not support the final finding.

  • Code at lib/vtls/vtls.c lines 132-147 confirms CURLOPT_ISSUERCERT (non-blob) is not compared (C2).
  • Code confirms case-insensitive comparison via Curl_safe_strcasecompare for CApath, CAfile, and pinned_key (C3, C4).
  • Code shows ca_info_blob IS compared (line 138), contradicting the claim for CURLOPT_CAINFO_BLOB, but issuer_cert_blob is missing (C1 partially contradicted).
  • The combined flaws allow connection reuse with weaker security parameters, enabling MITM attacks as described.
How this analysis ran 5 claims · 7 citations verified

Evidence check: judge said likely_valid but contradicted a central claim

Checked against curl master on 2021-06-11 (23eef2394cb8). 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
grounded
no model · 6 references checked out, 0 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
5 claims · 2341 tokens · $0.0002
3 · Evidence
1 code snippets
real curl source at 23eef2394cb8 · 5 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
8534 tokens · 15.3s · $0.0160
5 · Receipts
7 of 7 citations verified
every citation must point at code the judge was shown
Inspect the withdrawn draft reply

This draft belongs to the withdrawn judgment. It may contain unsupported claims.

Thank you for the detailed report. The code confirms three of the four specific flaws: CURLOPT_ISSUERCERT is not compared (line 132-147), paths and pinned_key use case-insensitive comparison (lines 139, 140, 147), and the pinned_key fingerprint is compared case-insensitively. However, CURLOPT_CAINFO_BLOB (ca_info_blob) IS compared at line 138, so only CURLOPT_ISSUERCERT_BLOB is missing from BLOB comparisons. These flaws allow connection reuse with weaker security settings, which is a valid security issue. We will address the missing issuer_cert and issuer_cert_blob checks and switch to case-sensitive comparisons for paths and fingerprints.

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

This model judgment was withdrawn. The claim assessments below are preserved for inspection and may be wrong.

Report claims

C1flaw contradicted

Curl_ssl_config_matches fails to consider BLOB type certificate values such as CURLOPT_CAINFO_BLOB and CURLOPT_ISSUERCERT_BLOB

Read the reasoning

The code compares ca_info_blob (CURLOPT_CAINFO_BLOB) at line 138, contradicting the claim that it fails to consider this BLOB type. However, there is no comparison for an issuer cert blob (CURLOPT_ISSUERCERT_BLOB), so the claim is partially correct for that option.

C2flaw supported

CURLOPT_ISSUERCERT value is not matched during SSL config comparison

Read the reasoning

The function compares version, verifypeer, verifyhost, verifystatus, cert_blob, ca_info_blob, CApath, CAfile, clientcert, random_file, egdsocket, cipher_list, cipher_list13, curves, and pinned_key. No issuer_cert field appears, confirming CURLOPT_ISSUERCERT is not matched.

C3flaw supported

Path names for capath, cainfo and pinned public key use case-insensitive comparison

Read the reasoning

All three path/key fields use Curl_safe_strcasecompare, which by name and convention performs case-insensitive comparison, confirming the flaw.

C4flaw supported

Pinned public key fingerprint set by CURLOPT_PINNEDPUBLICKEY sha256// is compared case-insensitively

Read the reasoning

The pinned_key field (which holds the CURLOPT_PINNEDPUBLICKEY value including sha256// fingerprints) is compared case-insensitively, exactly as claimed.

C5flaw supported

Curl_ssl_config_matches incorrectly compares SSL security options leading to improper connection reuse

Read the reasoning

The function's flawed comparison logic (missing issuer_cert and issuer_cert_blob checks, case-insensitive path and fingerprint comparisons) directly enables improper connection reuse as described.

What the report says about other projects

not addressed CWE-664 Improper Control of a Resource Through its Lifetime might fit

not addressed CWE-41 Improper Resolution of Path Equivalence

Read the original report (excerpt)

Full report on HackerOne ↗

## Summary: `Curl_ssl_config_matches` attempts to compare whether two SSL connections have identical SSL security options or not. The idea is to avoid reusing a connection that uses less secure, or completely different security options such as capath, cainfo or certificate/issuer pinning. Unfortunately this function has several flaws in it: 1. It completely fails to take into account "BLOB" type certificate values, such as set by `CURLOPT_CAINFO_BLOB` and `CURLOPT_ISSUERCERT_BLOB`. If the application can be made to initiate connection to a user specified location (where these BLOB options are not used) before the "more secure" connection using these options is made, the attacker can point the application to connect to the same address and port, effectively poisoning the connection cache with a connection that has been established with different cainfo or issuecert settings. This leads to attacker being able to neutralize these options and make libcurl ignore them for the connections for which they're set. I have no obvious CWE number for this one, but CWE-664 `Improper Control of a Resource Through its Lifetime` might fit. 2. `CURLOPT_ISSUERCERT` value is not matched. Similar to above. 3. Similarly, the function has an implementation flaw where path names use case-insensitive comparison for capath, cainfo and pinned public key paths. This can lead to a situation where if the attacker can specify the capath, cainfo or pinned public key name that have a different path capitalization. Again, if the attacker can specify some of these values for the connection that is performed before the later supposedly secure connection is made, the attacker is able to make the further connection use incorrect capath, cainfo or pinned public key. This is CWE-41 `Improper Resolution of Path Equivalence`. 4. Finally, the pinned public key fingerprint set by `CURLOPT_PINNEDPUBLICKEY` `sha256//` is incorrectly compared as case-insenstive value. If the attacker is able to create a otherwise valid certificate that has a fingerprint that has the same fingerprint string but with different capitalization (very difficult to pull off in practice), and the application could be tricked to use this value for `CURLOPT_PINNEDPUBLICKEY` and create a connection, later connection could be confused to think that the pinned public key is the same one. Exploiting any of these issues requires a …

Source code

lib/vtls/vtls.clines 128–151 · definition of Curl_ssl_config_matches
128bool
C5: The Curl_ssl_config_matches function at lines 128-151 contains the comparison logic with the omissions and case-insensitive comparisons documented in C2-C4.
129Curl_ssl_config_matches(struct ssl_primary_config *data,
130 struct ssl_primary_config *needle)
131{
132 if((data->version == needle->version) &&
C2: The comparison list at lines 132-147 includes no field for issuer_cert (non-blob CURLOPT_ISSUERCERT).
133 (data->version_max == needle->version_max) &&
134 (data->verifypeer == needle->verifypeer) &&
135 (data->verifyhost == needle->verifyhost) &&
136 (data->verifystatus == needle->verifystatus) &&
137 blobcmp(data->cert_blob, needle->cert_blob) &&
138 blobcmp(data->ca_info_blob, needle->ca_info_blob) &&
C1: Line 138 shows blobcmp(data->ca_info_blob, needle->ca_info_blob), meaning CURLOPT_CAINFO_BLOB is compared. However, no issuer_cert_blob field is compared, so CURLOPT_ISSUERCERT_BLOB is indeed omitted.
139 Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
C3: Line 139 uses Curl_safe_strcasecompare for CApath (capath).
140 Curl_safe_strcasecompare(data->CAfile, needle->CAfile) &&
C3: Line 140 uses Curl_safe_strcasecompare for CAfile (cainfo/cacert).
141 Curl_safe_strcasecompare(data->clientcert, needle->clientcert) &&
142 Curl_safe_strcasecompare(data->random_file, needle->random_file) &&
143 Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) &&
144 Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
145 Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) &&
146 Curl_safe_strcasecompare(data->curves, needle->curves) &&
147 Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key))
C3: Line 147 uses Curl_safe_strcasecompare for pinned_key (pinned public key).
C4: Line 147 compares pinned_key with Curl_safe_strcasecompare, making the fingerprint comparison case-insensitive.
148 return TRUE;
149
150 return FALSE;
151}