# SEH buffer overflow msgfmt_format_message

Oversized locale string passed to PHP MessageFormatter::formatMessage overflows a stack buffer in libicu's Locale constructor, corrupting the SEH chain with attacker bytes.

- Payout: $1,000
- Severity: high
- Program: Internet Bug Bounty
- Credited: fms
- Disclosed: 2019-10-13
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/170138
- Library page: https://bugbountylibrary.com/r/h1%3A170138
- Tags: domain:oss impact:rce kind:bounty platform:hackerone sev:high tech:php technique:fuzzing technique:source-review vuln:dos vuln:memory-corruption

**Target:** PHP ext/intl msgfmt_format_message / libicu Locale constructor
**Root cause:** PHP passes an unbounded user-supplied locale string into libicu's Locale constructor, which copies it into a fixed stack buffer without length validation, causing a stack-based buffer overflow.
**Steps:**
1. Call `MessageFormatter::formatMessage($locale, $pattern, $args)` with a very large locale string, e.g. `str_repeat("ABCE", 503566756/3)`.
2. PHP's `msgfmt_format_message` parses the locale via `zend_parse_method_parameters` with no length cap.
3. The locale is handed to libicu `Locale::Locale`, which writes past its stack buffer.
4. Observe write AV at `icuuc57!icu_57::Locale::Locale+0x27c` and SEH chain overwritten with `0x43424145` ('ABCE').
**How found:** Researcher fuzzed/experimented with the locale parameter of MessageFormatter::formatMessage, noticed libicu's Locale constructor lacked length checks, and crafted a huge repeated string to trigger a stack overflow visible in WinDbg's !exploitable as an overwritten SEH chain.
**Exploitation:** Attacker controls the overflow bytes (locale string) and overwrites the SEH handler chain with 'ABCE' (0x43424145), yielding an exploitable exception-handler-corrupted crash; full code execution would require crafting a locale payload with a controlled handler address and shellcode, not demonstrated in the report.
**Insight:** When a PHP extension forwards a user string to a C library constructor (here libicu Locale), check whether the library enforces its own length limits; oversized locale/format strings are a classic unvalidated-input path into native stack buffers.
