# Buffer Overflow in optimized_escape_html method

Integer overflow in Ruby CGI.escape_html's buffer size calc on 32-bit long platforms lets a >700MB string overflow the heap buffer.

- Payout: hidden
- Severity: medium
- Program: Internet Bug Bounty
- Found by: chamal
- Disclosed: 2022-01-22
- CVE: CVE-2021-41816
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/1455248
- Library page: https://bugbountylibrary.com/r/h1%3A1455248
- Tags: area:oss domain:oss impact:dos kind:bounty platform:hackerone sev:medium tech:ruby technique:regression technique:source-review vuln:dos vuln:memory-corruption

**Target:** CGI.escape_html in ext/cgi/escape/escape.c
**Root cause:** RSTRING_LEN(str) * HTML_ESCAPE_MAX_LEN is computed in 32-bit long on Windows, so a ~715M-char string wraps the allocation size to 1028 bytes while the copy loop still writes the full escaped length.
**Steps:**
1. On a platform where long is 4 bytes (Windows), call `CGI.escapeHTML` with a string of 715828054 characters.
2. Observe `ALLOCV_N(char, vbuf, RSTRING_LEN(str) * HTML_ESCAPE_MAX_LEN)` wraps 4,294,968,324 to 1028.
3. The escape loop writes up to 6 bytes per input char into the 1028-byte buffer, overflowing the heap.
4. Run attached escape.rb under a debugger to observe the crash.
**How found:** Code reading of escape.c: noticed RSTRING_LEN returns long and HTML_ESCAPE_MAX_LEN multiplication could overflow on 32-bit long, then computed 715828054*6 to confirm wrap to 1028.
**Insight:** When auditing C extensions, check size computations that multiply a length by a max-expansion constant in a `long`; on Windows long is 32-bit even on 64-bit builds, so attacker-controlled large strings can wrap allocations.
