HexBrain

curl · Report #3279804

Stack use-after-scope in HTTP/3 POST request processing via CURLOPT_POSTFIELDS

N/Astatus
highseverity
27upvotes
31 Jul 2025disclosed

Summary

Audit every libcurl POST in your stack. Treat CURLOPT_POSTFIELDS like explosives. Either switch to CURLOPT_COPYPOSTFIELDS or prove your pointer lives forever. No exceptions.

How it was found

Summary

A stack use-after-scope vulnerability exists in libcurl's HTTP/3 request processing when using CURLOPT_POSTFIELDS with stack-allocated buffers. libcurl retains a pointer to user-provided POST data but accesses it after the original stack frame has been destroyed, leading to memory corruption and potential denial of service.

The vulnerability occurs in Curl_pretransfer() at transfer.c:569 when libcurl calls strlen() on the previously stored POST data pointer that now points to invalid stack memory.

Steps to Reproduce / Proof of Concept

Environment

  • libcurl version: 8.16.0-DEV (master branch)
  • Compiler: Clang 20.1.8 with AddressSanitizer
  • Platform: macOS (ARM64)
  • Configuration: HTTP/3 enabled with ngtcp2/nghttp3

Reproduction Steps

  1. Build libcurl with ASAN:
  export CC=clang
  export CFLAGS="-O1 -g -fsanitize=address,undefined"
  ./configure --with-openssl --with-nghttp2 --with-nghttp3 --with-ngtcp2
  make
  1. Compile the reproducer:
  // http3_crash_poc.c
  #include <curl/curl.h>
  #include <string.h>

  int main() {
      CURL *curl = curl_easy_init();

      // Stack-allocated buffer that goes out of scope
      {
          char body_data[257];
          memset(body_data, 'A', 256);
          body_data[256] = '\0';

          curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
          curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_3);
          curl_easy_setopt(curl, CURLOPT_POST, 1L);
          curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body_data); // Vulnerable call
          curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 50L);
      } // body_data goes out of scope here

      // libcurl accesses invalid memory during transfer
      curl_easy_perform(curl);
      curl_easy_cleanup(curl);
      return 0;
  }
  1. Compile and run:
  clang -fsanitize=address http3_crash_poc.c -lcurl -o poc
  ./poc

Crash Output

  ==3720==ERROR: AddressSanitizer: stack-use-after-scope on address 0x00016fa21470
  READ of size 45 at 0x00016fa21470 thread T0
      #0 strlen
      #1 Curl_pretransfer transfer.c:569
      #2 multi_runsingle multi.c:2376
      #3 curl_multi_perform multi.c:2756
      #4 easy_transfer easy.c:705
      #5 easy_perform easy.c:813

  SUMMARY: AddressSanitizer: stack-use-after-scope transfer.c:569 in Curl_pretransfer

Fuzzer Discovery

This vulnerability was discovered using a custom libFuzzer fuzzing harness.

Technical Analysis

Root Cause

The vulnerability stems from libcurl's CURLOPT_POSTFIELDS behavior:

  1. libcurl stores the pointer but doesn't copy the data
  2. The application's stack buffer becomes invalid after scope exit
  3. libcurl later dereferences the invalid pointer in Curl_pretransfer()

Affected Code Path

curl_easy_setopt(CURLOPT_POSTFIELDS) → curl_easy_perform() → Curl_pretransfer() → strlen(invalid_pointer) → CRASH

Recommended Fix

  1. Documentation: Clarify that CURLOPT_POSTFIELDS data must remain valid until transfer completion
  2. API Enhancement: Consider adding bounds checking or automatic copying for stack-detected pointers
  3. Alternative API: Promote CURLOPT_COPYPOSTFIELDS for safer usage patterns

Impact

Security Impact

  1. Denial of Service: Guaranteed crash leading to application termination
  2. Memory Corruption: Use-after-scope can lead to unpredictable behavior
  3. Potential Code Execution: In specific circumstances, memory corruption could be leveraged for control flow hijacking

Affected Scenarios

  • Applications using libcurl for HTTP/3 requests with POST data
  • Any code pattern where CURLOPT_POSTFIELDS points to stack-allocated memory
  • Particularly affects:
    • HTTP/3 client applications
    • API clients using stack buffers for request bodies
    • Embedded systems with limited heap usage

Real-World Exposure

  • Language bindings: Many curl bindings may inadvertently create this pattern
  • Example applications: CLI tools, web scrapers, API clients
  • Severity: High due to HTTP/3 adoption growth and remote exploitability

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original