curl · Report #3229490
Heap Buffer Overflow in libcurl curl_slist_append via Unterminated String
Summary
libcurl heap-buffer-overflow: API contract vs. memory safety — you decide.
An easily reproducible heap buffer overflow exists in libcurl’s curl_slist_append() function, triggered by passing a non-NUL-terminated string. The function internally calls strdup(), which in turn invokes strlen() with no bounds check—leading to out-of-bounds heap reads if the input isn’t NUL-terminated.
Steps to Reproduce:
• Allocate a buffer, e.g. 256 bytes.
• Fill it with non-zero bytes; don’t NUL-terminate.
• Call curl_slist_append(NULL, buffer);
• Observe AddressSanitizer reporting a heap-buffer-overflow.
Minimal PoC:
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *buf = malloc(4);
memcpy(buf, "\xbc\x07\x7a\x02", 4); // No NUL
curl_slist_append(NULL, buf); // 💥 Heap overflow
free(buf);
}
Command:
clang -fsanitize=address -g poc.c -lcurl -o curl_poc
./curl_poc
Impact:
Confidentiality: High — arbitrary heap memory can be leaked. Availability: Medium — easy DoS/crash on malformed input. Integrity: Low — limited to reading, not writing.
Attack surface: Any code, binding, or fuzz harness using libcurl and not strictly validating NUL-termination on user input (think FFI in Rust, Go, Python, etc.)
Why This Still Matters:
C contracts ≠ modern memory safety. Hardened builds, fuzzing, and language bindings can all hit this crash in the real world. Just because the spec says “don’t do that” doesn’t mean you should ship APIs that crash on malformed input.
Takeaway:
If you want to break (or secure) memory in 2025, don’t trust legacy API contracts. Trust code that enforces bounds, even when nobody’s watching.
“We don’t blame the maintainers for upholding a legacy view of C. But we also don’t stop at ‘Not Applicable.’ Because memory doesn’t care about intent. It cares about bounds.”
Stay glitchy, @geeknik
How it was found
#Summary
A heap buffer overflow vulnerability exists in libcurl's curl_slist_append() function in lib/slist.c:94. When the function is called with a non-null-terminated string, the internal strdup() call triggers strlen() to read beyond allocated buffer boundaries, leading to a heap buffer overflow. This vulnerability can be triggered through various libcurl APIs that process user-controlled string data without proper null termination validation.
#Steps to Reproduce (STR/POC):
- Allocate a buffer of any size (e.g., 256 bytes)
- Fill the buffer completely with non-null bytes (no null terminator)
- Call curl_slist_append(NULL, buffer)
- The strlen() call within strdup() will read past the buffer boundary
- AddressSanitizer detects heap buffer overflow
Minimal reproducer:
char *buffer = malloc(256);
memset(buffer, 'A', 256); // No null termination
curl_slist_append(NULL, buffer); // Triggers overflow
{F4507009}
Built and tested with libcurl, git commit a487a4e4bddb301e44360c09a8167adc52c31e71.
Impact
Impact:
- Confidentiality: High - Out-of-bounds read can leak sensitive heap memory contents
- Integrity: Low - Limited write capability
- Availability: Medium - Potential denial of service via crash
The vulnerability allows attackers to:
- Read arbitrary heap memory beyond allocated boundaries
- Potentially crash applications using libcurl
- In some scenarios, may lead to information disclosure of sensitive data from adjacent heap allocations
Attack Vectors:
- HTTP header processing
- URL parsing with malformed components
- Cookie handling
- Custom request methods
- Any libcurl API accepting string parameters
CVSS Score: 7.3 (High)
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L