✓ProveIt
Examples / Report #1546268 Saved analysis

CVE-2022-27775: Bad local IPv6 connection reuse

curl · 2022-04-218.4s analysis · $0.009 in model calls

What the report claims

Curl reuses IPv6 connections without considering zone index, causing incorrect connection reuse.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2022-27775 Bad local IPv6 connection reuse

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 report describes a concrete, plausible flaw in IPv6 connection reuse with zone index and provides reproducible steps.
  • The provided source code snippets do not include the connection reuse logic (curl_conn.c, Curl_conninfo, etc.) that would confirm or contradict the claim.
  • Per the rules, when the deciding code is not provided, claims are not_verifiable and the verdict is needs_human.
What still needs checking
  • Source code for connection pooling/reuse (likely lib/conncache.c, lib/url.c, or lib/connect.c in this revision) showing how IPv6 addresses are compared for reuse, including whether zone index (scope_id) is part of the comparison.
How this analysis ran 5 claims · 0 citations verified

Checked against curl master on 2022-04-21 (e498a9b1fe59). Dev 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 · 1 references checked out, 0 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
5 claims · 1426 tokens · $0.0002
3 · Evidence
4 code snippets
real curl source at e498a9b1fe59
4 · Judgment
Nemotron-3-Ultra-550b-a55b
5165 tokens · 6.4s · $0.0086
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 detailed report and reproduction steps. The connection reuse logic for IPv6 (including zone index handling) is not in the source snippets we were given for triage. Could you point to the specific file and function (e.g., in conncache.c or connect.c) where IPv6 addresses are compared for connection reuse? That will let us verify whether the zone index is checked.

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

Report claims

C1flaw not verifiable

curl reuses connections based on IPv6 address without checking zone index

Read the reasoning

The claim concerns connection reuse logic for IPv6 addresses with zone index. The provided source snippets (urldata.h, easy.c, urlapi.c) do not contain connection pooling/reuse code. Files referenced in the claim (curl_conn.c, Curl_conninfo, Curl_conninfo_copy) are not included in the provided source.

C2location not verifiable

in connection reuse logic for IPv6 addresses

Read the reasoning

The claim points to connection reuse logic in curl_conn.c and related functions. None of these files or functions appear in the provided source code snippets.

C3trigger not verifiable

using IPv6 address with zone index in URL

Read the reasoning

The claim describes using an IPv6 address with zone index in a URL (e.g., `[ipv6addr%25lo]`). The provided urlapi.c snippet only shows the `curl_url()` allocator; the URL parsing logic that handles zone indices is not present.

C4impact not verifiable

disclosure of confidential information via wrong connection reuse

Read the reasoning

The impact claim depends on the underlying flaw (C1) being real. Since the connection reuse code is not provided, the impact cannot be verified from the given source.

C5reproduction not verifiable

connect to server via IPv6 address and reuse with zone index variant

Read the reasoning

The reproduction steps are clear, but the code path they exercise (connection reuse with IPv6 zone index) is not in the provided source snippets.

Read the original report

Full report on HackerOne ↗

## Summary: Curl doesn't consider IPv6 address zone index when doing connection reuse. if connection exists to specific IPv6 address (and other conditions for connection reuse are fulfilled) it will be reused for connections regardless of the zone index. ## Steps To Reproduce: 1.Set up a fake server: `echo -ne 'HTTP/1.1 200 OK\r\nContent-Length: 6\r\n\r\nHello\n' | nc -6 -v -l -p 9999` 2. curl "http://[ipv6addr]:9999/x" "http://[ipv6addr%25lo]:9999/y" Both connections arrive to the test server: ``` Listening on :: 9999 Connection received on somehost someport GET /x HTTP/1.1 Host: [ipv6addr]:9999 User-Agent: curl/7.83.0-DEV Accept: */* GET /y HTTP/1.1 Host: [ipv6addr]:9999 User-Agent: curl/7.83.0-DEV Accept: */* ``` Clearly the 2nd connection should fail as the address is not available at interface lo. (Lone connection to `http://[ipv6addr%25lo]:9999/` fails with `curl: (7) Couldn't connect to server`) ## Impact Reuse of wrong connection leading to potential disclosure of confidential information. Practical impact of this vulnerability is very low, due to the rarity of situation where interfaces would have identical addresses. The attacker would also need to be able to manipulate the addresses the victim app connects to (making it first connect to interface controlled by the attacker).Finally, it doesn't seem likely that TLS would be used for such connections, making the scenario rather insecure to begin with.It seems likely that if the attacker has ability to set up interfaces with identical addresses they would have easier way to compromise the system anyway.

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};
lib/easy.clines 706–709 · definition of curl_easy_perform
706CURLcode curl_easy_perform(struct Curl_easy *data)
707{
708 return easy_perform(data, FALSE);
709}
lib/urlapi.clines 1167–1170 · definition of curl_url
Show 4 lines (not cited by the judge)
1167CURLU *curl_url(void)
1168{
1169 return calloc(sizeof(struct Curl_URL), 1);
1170}
lib/easy.clines 282–305 · definition of curl_easy_init
Show 24 lines (not cited by the judge)
282struct Curl_easy *curl_easy_init(void)
283{
284 CURLcode result;
285 struct Curl_easy *data;
286
287 /* Make sure we inited the global SSL stuff */
288 if(!initialized) {
289 result = curl_global_init(CURL_GLOBAL_DEFAULT);
290 if(result) {
291 /* something in the global init failed, return nothing */
292 DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
293 return NULL;
294 }
295 }
296
297 /* We use curl_open() with undefined URL so far */
298 result = Curl_open(&data);
299 if(result) {
300 DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
301 return NULL;
302 }
303
304 return data;
305}