# Read and write beyond bounds in mod_sed

mod_sed in Apache httpd 2.4.52 and earlier has use-after-free, int overflow, and logic bugs enabling remote unauthenticated heap out-of-bounds read/write.

- Payout: hidden
- Severity: high
- Program: Internet Bug Bounty
- Found by (vendor credit): Ronald Crane (Zippenhop LLC)
- Found by: tdp3kel9g
- Disclosed: 2022-04-14
- CVE: CVE-2022-23943
- Write-up quality: 9/10
- Original: https://hackerone.com/reports/1511619
- Library page: https://bugbountylibrary.com/r/h1%3A1511619
- Tags: area:web domain:web impact:data-leak impact:dos impact:rce kind:bounty platform:hackerone sev:high tech:linux technique:incomplete-fix technique:source-review vuln:dos vuln:memory-corruption

**Target:** mod_sed input/output filter (sed1.c, mod_sed.c) in httpd
**Root cause:** dosub() fails to update step_vars->loc1/loc2 after linebuf reallocation (UAF); grow_buffer() computes spendsize as int so 0x80000000 becomes negative, placing *spend before *buffer; sed_write_output() memcpy's sz bytes into a ctx->bufsize buffer when status != APR_SUCCESS.
**Steps:**
1. Configure `<Location /bug17h> AddInputFilter Sed htm; InputSed "s/0/zzzzzz/g"`
2. POST ~16MB of '0' bytes to /bug17h/postform.htm with Content-Length 16777219
3. grow_line_buffer reallocates linebuf during dosub(); loc1/loc2 still point to old buffer
4. Next dosub() call to place() computes n = al2 - al1 with mismatched buffers, memcpy(sp, al1, n) reads/writes OOB
5. For int-overflow variant: send >0x80000000 bytes; grow_buffer sets spendsize negative, *spend = *buffer + spendsize lands 0x80000000 before linebuf
6. appendmem_to_linebuf memcpy(eval->lspend, sz, len) writes attacker data to wrong heap location
**How found:** Author was pursuing a separate int-overflow POC in grow_buffer() and noticed dosub() didn't refresh loc1/loc2 after genbuf/linebuf reallocation; then code-read sed_write_output() and spotted the else-branch memcpy of sz into a bufsize buffer when status != APR_SUCCESS.
**Exploitation:** Remote unauthenticated attacker sends large POST body to a location with InputSed substitution; expansion causes linebuf reallocation leaving stale loc pointers, or >2GB body triggers signed int overflow in grow_buffer, redirecting lspend before the buffer so subsequent memcpy writes attacker-controlled bytes to attacker-chosen heap offset.
**Escalation:** Attacker controls exact content and amount written (payload minus 0x80000000), enabling heap corruption toward control-flow hijack; also DoS via expansion.
**Insight:** In filter modules, any cached pointer into a growable buffer must be re-derived after every append that may realloc; also audit signed int size arithmetic in buffer-doubling code on 64-bit builds, and check error-path branches that skip the size guard.
