✓ProveIt
Examples / Report #2819666 Saved analysis

Exploitable Format String Vulnerability in curl_mfprintf Function

curl · 2024-11-0411.1s analysis · $0.011 in model calls

What the report claims

The curl_mfprintf function in curl_printf.h contains a format string vulnerability that allows an attacker to inject arbitrary format specifiers, potentially leading to memory disclosure, crashes, or sensitive data leakage.

Compare with curl's recorded outcome

Labeled AI slop

curl's maintainer lists this report as AI slop

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

ProveIt's finding

Code contradicts the claim

The code provides evidence against the report's central claim. Review the cited lines before deciding.

curl policy: API misuse
Why this finding?
  • curl_mfprintf is a printf-family variadic function designed to accept a trusted format string and matching arguments
  • The reported behavior only occurs when an application passes user-controlled input as the format string — a clear case of API misuse
  • The project policy explicitly lists 'API misuse' as not a security issue: 'If a reported issue only triggers by an application using the API in a way that is not documented to work or even documented to not work, it is probably not going to be considered a security problem.'
  • The reporter's own test code demonstrates the misuse: passing a format string with specifiers (%x) but no corresponding variadic arguments
How this analysis ran 6 claims · 8 citations verified

Checked against curl master on 2024-11-04 (3a35901a115e). 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 · 1300 tokens · $0.0002
3 · Evidence
2 code snippets
real curl source at 3a35901a115e
4 · Judgment
Nemotron-3-Ultra-550b-a55b
6037 tokens · 8.0s · $0.0104
5 · Receipts
8 of 8 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 curl_mfprintf function is a printf-style variadic function where the format string is expected to be a trusted/constant string provided by the caller, not user-controlled input. The behavior you demonstrate occurs only when an application misuses the API by passing attacker-controlled data as the format string without supplying matching arguments. Per curl's security policy, API misuse is explicitly not considered a security vulnerability. If you believe there is a case where curl itself passes untrusted data as the format string to curl_mfprintf, please provide the specific code path.

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

Report claims

C1flaw contradicted

curl_mfprintf function contains a format string vulnerability that allows an attacker to inject arbitrary format specifiers

Read the reasoning

The function behaves as a standard printf-family function. The 'vulnerability' only manifests when an application misuses the API by passing user-controlled input as the format string without providing corresponding variadic arguments. This is API misuse, not a flaw in curl_mfprintf itself.

C2flaw contradicted

The function allows injection of arbitrary format specifiers

Read the reasoning

The function allows format specifiers in the format string by design — that is its documented purpose. The claim frames intended behavior as a vulnerability.

C3flaw contradicted

This can lead to unauthorized access to memory content

Read the reasoning

The function does not read arbitrary memory on its own; any memory exposure requires the application to misuse the API by providing a malicious format string without corresponding arguments.

C4flaw contradicted

Potential application crashes

Read the reasoning

A crash from mismatched format specifiers and arguments is a consequence of incorrect API usage, not a vulnerability in the function.

C5flaw contradicted

Leakage of sensitive data

Read the reasoning

Same as C3 and C4: the risk only materializes through API misuse, which the project policy explicitly excludes from security issues.

C6flaw contradicted

Exploitable format string vulnerability in curl_mfprintf function

Read the reasoning

The claim summarizes the preceding points. The function has no flaw; the reporter's test case demonstrates API misuse by passing user input as the format string with no matching arguments.

Read the original report

Full report on HackerOne ↗

Summary: The curl_mfprintf function in the curl_printf.h file contains a format string vulnerability that allows an attacker to inject arbitrary format specifiers. This can lead to unauthorized access to memory content, potential application crashes, or leakage of sensitive data. Steps To Reproduce: Prepare the Test Code: Create a new file named test_printf.c with the following content: #include <stdio.h> #include "curl_printf.h" int main() { char* user_input = "%x %x %x %x"; // Attempt to read memory content curl_mfprintf(stdout, user_input); // Passing user-controlled input to the vulnerable function return 0; } Compile the Code: Compile the test program with the following command: bash gcc -o test_printf test_printf.c -I./lib -I./include -L./lib/.libs -lcurl Execute the Code: Run the compiled program: bash ./test_printf Observe the Output: The output should display memory content, which confirms that the vulnerability is exploitable. ## Impact This vulnerability allows an attacker to use format string specifiers to access arbitrary memory locations. By exploiting this issue, an attacker could potentially: Leak sensitive information from the process memory. Cause a denial-of-service by crashing the application. Further exploit the application depending on the context of the memory exposure.

Source code

lib/mprintf.clines 1193–1201 · definition of curl_mfprintf
1193int curl_mfprintf(FILE *whereto, const char *format, ...)
C1: curl_mfprintf is a variadic printf-style function that takes a format string and corresponding arguments; the format string is expected to be a trusted/constant string, not user-controlled input
C2: Function signature shows it accepts a format string followed by variadic arguments matching the format specifiers
C3: Unauthorized memory access would only occur if the caller passes a format string with specifiers but fails to supply matching arguments — a caller bug, not a curl bug
C4: Crashes would only result from API misuse (e.g., format string expecting arguments that are not provided)
C5: Data leakage would require the application to pass a user-controlled format string — an API misuse scenario
C6: The function is a standard printf variant; the reported 'exploitable vulnerability' is the function working as designed when misused
1194{
1195 int retcode;
1196 va_list ap_save; /* argument pointer */
1197 va_start(ap_save, format);
1198 retcode = formatf(whereto, fputc_wrapper, format, ap_save);
C1: The function passes the format string directly to formatf, which is the intended design for a printf-family function
C2: formatf processes the format string with the provided va_list; if the caller passes a user-controlled format string without matching arguments, that is caller error
1199 va_end(ap_save);
1200 return retcode;
1201}
src/tool_main.clines 227–287 · definition of main
227int main(int argc, char *argv[])
228#endif
229{
230 CURLcode result = CURLE_OK;
231 struct GlobalConfig global;
232 memset(&global, 0, sizeof(global));
233
234 tool_init_stderr();
235
236#ifdef _WIN32
237 /* Undocumented diagnostic option to list the full paths of all loaded
238 modules. This is purposely pre-init. */
239 if(argc == 2 && !_tcscmp(argv[1], _T("--dump-module-paths"))) {
240 struct curl_slist *item, *head = GetLoadedModulePaths();
241 for(item = head; item; item = item->next)
242 printf("%s\n", item->data);
243 curl_slist_free_all(head);
244 return head ? 0 : 1;
245 }
246 /* win32_init must be called before other init routines. */
247 result = win32_init();
248 if(result) {
249 errorf(&global, "(%d) Windows-specific init failed", result);
250 return (int)result;
251 }
252#endif
253
254 if(main_checkfds()) {
255 errorf(&global, "out of file descriptors");
256 return CURLE_FAILED_INIT;
257 }
258
259#if defined(HAVE_SIGNAL) && defined(SIGPIPE)
260 (void)signal(SIGPIPE, SIG_IGN);
261#endif
262
263 /* Initialize memory tracking */
264 memory_tracking_init();
265
266 /* Initialize the curl library - do not call any libcurl functions before
267 this point */
268 result = main_init(&global);
269 if(!result) {
270 /* Start our curl operation */
271 result = operate(&global, argc, argv);
272
273 /* Perform the main cleanup */
274 main_free(&global);
275 }
276
277#ifdef _WIN32
278 /* Flush buffers of all streams opened in write or update mode */
279 fflush(NULL);
280#endif
281
282#ifdef __VMS
283 vms_special_exit(result, vms_show);
284#else
285 return (int)result;
286#endif
287}