✓ProveIt
Examples / Report #1213181 Saved analysis

CVE-2021-22923: Metalink download sends credentials

curl · 2021-05-309.5s analysis · $0.009 in model calls

What the report claims

When compiled with libmetalink and used with --metalink and --user, curl sends credentials to any host referenced in a metalink file, even without TLS, potentially leaking credentials intended for a specific target.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2021-22923 Metalink download sends credentials

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 and plausible attack scenario: metalink files referencing third-party hosts could receive credentials provided for the original target.
  • However, the provided source code (only lib/urldata.h lines 122-199) does not contain the metalink parsing logic, credential handling for metalink transfers, or the CURLOPT_LOCATIONTRUSTED implementation needed to verify or contradict the claims.
  • All six claims are not_verifiable against the given code snippets. A human reviewer needs to examine the metalink implementation (likely lib/metalink.c) and the credential propagation logic.
What still needs checking
  • Source code for metalink handling (likely lib/metalink.c)
  • Credential propagation logic when following metalink references
  • Implementation of CURLOPT_LOCATIONTRUSTED and whether it applies to metalink
How this analysis ran 6 claims · 0 citations verified

Checked against curl master on 2021-05-30 (1c1d9f1affbd). 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 · 2 references checked out, 0 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
6 claims · 1468 tokens · $0.0002
3 · Evidence
1 code snippets
real curl source at 1c1d9f1affbd · 3 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
5377 tokens · 6.9s · $0.0087
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 metalink credential forwarding behavior you describe is plausible and concerning. However, the code snippets provided for triage (only lib/urldata.h) do not contain the metalink parsing or credential handling logic needed to verify the claims. Could you point to the specific source files (e.g., lib/metalink.c) and functions where credentials are applied to metalink-referenced URLs? That would allow us to confirm whether CURLOPT_LOCATIONTRUSTED or similar protections are missing for metalink transfers.

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

Report claims

C1flaw not verifiable

curl sends credentials to any host referenced in a metalink file, even without TLS

Read the reasoning

The claim describes metalink credential forwarding behavior, but the provided source code (lib/urldata.h lines 122-199) only shows typedefs and includes. The metalink parsing and credential handling implementation (likely in lib/metalink.c or similar) is not provided, so the claim cannot be verified against the given code.

C2flaw not verifiable

credentials intended for a target site may end up being sent to outside hosts

Read the reasoning

Same as C1: the code that handles CURLOPT_USERPWD and CURLOPT_HTTPAUTH in the context of metalink transfers is not in the provided snippets.

C3flaw not verifiable

the leak occurs for http and ftp protocols without transport layer security

Read the reasoning

While deterministic checks confirm http and ftp symbols exist at this revision, the credential leak logic for those protocols during metalink processing is not shown in the provided code.

C4flaw not verifiable

the behavior is unexpected and insecure

Read the reasoning

The claim references CURLOPT_LOCATIONTRUSTED behavior for metalink, but the implementation of that option and its interaction with metalink is not in the provided source.

C5flaw not verifiable

credentials can be seen by the target host and anyone in man in the middle position

Read the reasoning

This describes the consequence of the alleged flaw. The code path that would send Authorization headers to metalink-referenced hosts is not provided.

C6flaw not verifiable

the leak occurs when using --metalink with --user and a metalink file referencing different hosts

Read the reasoning

The CURLOPT_METALINK option handling and its interaction with --user credentials is not shown in the provided source snippet.

What the report says about other projects

not addressed CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor) might be a more accurate CWE

Read the original report

Full report on HackerOne ↗

## Summary: When compiled `--with-libmetalink` and used with `--metalink` and `--user` curl will use the credentials for any further transfers performed. This includes different hosts and protocols, even ones without transport layer security such as `http` and `ftp`. As a result the credentials only intended for the target site may end up being sent to outside hosts, and without transport layer security, and may be intercepted by attackers in man in the middle network position. For example HTTP redirects will not leak the credentials to other hosts unless if `--location-trusted` is used, thus this is unexpected and insecure behaviour. ## Steps To Reproduce: 1. Configure libcurl `--with-libmetalink` and build libcurl 2. Have metalinktest.xml with `<url>` referencing data on different host than testsite and using `http` protocol 3. Execute: `curl --metalink --user professor:Joshua https://testsite/metalinktest.xml` The credentials can be seen by the target host and anyone in man in the middle position: `Authorization: Basic cHJvZmVzc29yOkpvc2h1YQ==` ## Remarks CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor) might be a more accurate CWE. ## Fix - Perhaps `--location-trusted` should be extended to apply to `--metalink` as well ## Impact Leak of credentials to unauthorized parties§

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};