# Read beyond bounds via ap_rwrite() [zhbug_httpd_47.2]

Signed int nbyte in ap_rwrite() sign-extends to apr_size_t len, creating a giant bucket that reads past the heap buffer and leaks memory to the client.

- Payout: hidden
- Severity: low
- Program: Internet Bug Bounty
- Found by (vendor credit): Ronald Crane (Zippenhop LLC)
- Found by: tdp3kel9g
- Disclosed: 2022-07-09
- CVE: CVE-2022-28614
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/1595299
- Library page: https://bugbountylibrary.com/r/h1%3A1595299
- Tags: area:web domain:web impact:data-leak impact:dos kind:bounty platform:hackerone sev:low tech:linux technique:source-review vuln:dos vuln:info-disclosure vuln:memory-corruption

**Target:** httpd server core ap_rwrite()/buffer_output() with mod_lua r:puts()
**Root cause:** ap_rwrite() passes its signed int nbyte to buffer_output() whose len parameter is apr_size_t; a negative nbyte sign-extends into a huge length, creating a transient bucket claiming 0xffffffffnnnnnnnn bytes over a buffer of only 0xnnnnnnnn bytes.
**Steps:**
1. Enable mod_lua and add `SetOutputFilter DATA` for a location serving a Lua handler that does `r:puts(r:requestbody())`.
2. Create a file of 0x80000000 bytes of 'a' named bug47.2.bin.
3. `curl -X POST -T bug47.2.bin http://127.0.0.1/bug47.2/bug47.2.lua`
4. At ap_rwrite() breakpoint observe nbyte == 0x80000000; in buffer_output() len == 0xffffffff80000000.
5. ap_fwrite() creates a transient bucket of that length; data_out_filter() base64-encodes past the real buffer end.
6. Response body contains 'YWFh' repeats then a block of non-'a' heap data.
**How found:** Code review of /server/protocol.c noticing the int-to-apr_size_t mismatch between ap_rwrite()'s nbyte and buffer_output()'s len, then building a Lua echo handler plus DATA output filter to force chunked reads and observe the over-read under a debugger.
**Exploitation:** Attacker POSTs a >2GB body to a Lua endpoint that echoes it via r:puts(); the sign-extended length makes the DATA output filter base64-encode beyond the allocated buffer, returning adjacent heap contents in the HTTP response. Often crashes the worker (DoS).
**Insight:** Audit signed/unsigned width mismatches at API boundaries where a length is forwarded to a size_t parameter; a negative length becomes a huge bucket. Force small-chunk output filters (like DATA/base64) to convert an over-read into a visible leak in the response body.
