Skip to main content
← All libraries
Network · C

How to fuzz libcurl

Billions of devices use libcurl — a URL parse bug here is a universal vulnerability.

libcurl's URL parser, cookie engine, and protocol-specific handlers (HTTP, FTP, IMAP, SMTP, SCP, SFTP) each parse attacker-influenced strings. Its IDN hostname normalisation and HSTS header logic have historically contained subtle length miscalculations that only fuzzing reliably surfaces.

Common bug classes

  • Heap buffer overflow in URL host component normalisation
  • Integer overflow in cookie domain attribute length check
  • Out-of-bounds read in HTTP/2 header decompression
  • Use-after-free in multi-handle connection reuse logic
  • SSRF via lenient URL scheme parsing in redirect follow

Recommended setup

Fuzzers

  • AFL++
  • libFuzzer
  • Honggfuzz

Sanitizers

  • ASan
  • UBSan

Harness scaffold

#include <stdint.h>
#include <stddef.h>
#include <curl/curl.h>

static size_t discard(void *ptr, size_t sz, size_t nmemb, void *data) {
  (void)ptr; (void)data; return sz * nmemb;
}

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  if (size < 8) return 0;
  char url[512];
  size_t url_len = size < 511 ? size : 511;
  memcpy(url, data, url_len); url[url_len] = '';
  CURL *curl = curl_easy_init();
  if (!curl) return 0;
  curl_easy_setopt(curl, CURLOPT_URL, url);
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, discard);
  curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 0L);
  curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
  /* URL parse only — no actual network I/O */
  CURLU *u = curl_url();
  curl_url_set(u, CURLUPART_URL, url, 0);
  curl_url_cleanup(u);
  curl_easy_cleanup(curl);
  return 0;
}

Save this as fuzz_target.cc, build with your compiler + sanitizer flags, and you have a working starting point.

Notable CVEs found by fuzzing

  • CVE-2023-38545
  • CVE-2022-27778
Start fuzzing libcurl on Fuzze.rs →

Push the harness above + a Dockerfile. First month 50% off.