CVE-2026-109618 · Unauthenticated POST → RCE
PHP 8.5.11 Apache prefork · mod_php memory_limit=16M
Stage 1
Reach the interrupted insertion

A single POST body carries three fields. The array-style name routes PHP into a key-insert helper that bumps the hash-table counters before allocating the key:

=<binary>&a=1&<name>[x]=1

The second allocation exceeds memory_limit, leaving an incomplete bucket counted in $_POST.

Stage 2
Fill the bucket with controlled data

Heap grooming plants useful bytes where PHP reads the bucket. A small hash table takes a 320-byte allocation; the 276-byte binary value lands in the same size class.

PHP frees those copies, then a=1 reuses the memory — attacker bytes remain, shaped to look like a value pointing at a fake array.

Stage 3
Turn array cleanup into a call

The fake array holds a destructor callback — the function PHP calls to free each element. The attacker aims it at system() and points the element at a command:

dtor → &system()  element → "cmd"

PHP calls the address without checking it, so any native function is reachable.


Request shutdown · cleanup path
Cleanup path
From failed request to command execution
Request initialization fails (alloc over memory_limit)
Request shutdown destroys $_POST
Unfinished bucket read as an array
PHP destroys the fake array
Callback invokes system(command)
Datadog Security Labs