# Heap overflow in curl_escape

PHP curl_escape passes a 0xffffffff-length string to libcurl's curl_easy_escape, whose size_t alloc wraps to 0, causing a heap overflow write.

- Payout: hidden
- Severity: high
- Program: Internet Bug Bounty
- Found by: hoangnguyen
- Disclosed: 2019-11-12
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/160295
- Library page: https://bugbountylibrary.com/r/h1%3A160295
- Tags: area:oss domain:oss impact:dos kind:bounty platform:hackerone sev:high tech:curl tech:php technique:source-review vuln:memory-corruption

**Target:** PHP curl extension / libcurl curl_easy_escape
**Root cause:** curl_easy_escape computes alloc = inlength + 1 in size_t; with inlength 0xffffffff this wraps to 0, malloc(0) returns a tiny buffer, and length = alloc-1 becomes 0xffffffff, so the copy loop writes far past the allocation.
**Steps:**
1. Call PHP curl_escape with a string of length 0xffffffff (e.g. `str_repeat("A",0xffffffff)`) and memory_limit -1.
2. PHP passes str_len as size_t to curl_easy_escape, truncated to int inlength = 0xffffffff.
3. libcurl computes alloc = 0xffffffff + 1 = 0 (size_t wrap), malloc(0) returns a minimal buffer.
4. length = alloc - 1 = 0xffffffff; the while loop copies bytes into ns[strindex++] far beyond the buffer, causing SIGSEGV/heap overflow.
**How found:** Source review of PHP's curl_escape wrapper and libcurl's curl_easy_escape, spotting the size_t addition and the alloc-1 length computation as an integer overflow candidate, then confirming with a crafted test script under gdb.
**Exploitation:** Local crash / potential heap corruption via a single PHP call with an oversized string; requires memory_limit disabled and ability to allocate ~4GB string.
**Insight:** When a wrapper passes a size_t length into a C API taking int, check the callee's `len+1` allocation math for wrap; malloc(0) plus `length = alloc-1` turns into an effectively unbounded copy loop.

