---
type: Article
title: "Melting the Flesh of PHP's Memory Hardening"
description: "PHP's heap hardening initiative set out to stop popular heap exploitation techniques. The first security study of it finds the mitigations defeat current-generation exploits but not adapted ones: it names the flaw that lets specific mitigations be bypassed and gives new strategies generic across built-in PHP objects from an out-of-bounds write or use-after-free - even a single-byte overflow."
resource: "https://www.usenix.org/conference/usenixsecurity26/presentation/wu-yifan"
tags: [article, webseclist-reference, php, memory-corruption, rce, mitigation, filter-bypass, owasp-a05-2021]
generated:
  by: webseclist-refs/1
  at: "2026-08-19T13:03:27+00:00"
status: stable
stale_after: 2027-08-19
sources:
  - id: original
    resource: "https://www.usenix.org/conference/usenixsecurity26/presentation/wu-yifan"
    title: "Melting the Flesh of PHP's Memory Hardening"
    author: Yifan Wu, Xiaochuan Yu, Zhiyun Qian
also_at:
  - "https://www.usenix.org/system/files/usenixsecurity26-wu-yifan.pdf"
authors:
  - Yifan Wu
  - Xiaochuan Yu
  - Zhiyun Qian
canonical_url: ""
cited_by:
  - "2026-ai.md:89"
commit: ""
content_sha256: edf21e37428199d9823961e64184be8566441ddcb5c5509b81f704e0fcc02e8e
depth: full
depth_reason: default
kind: article
language: ""
licence: unknown
original_url: "https://www.usenix.org/conference/usenixsecurity26/presentation/wu-yifan"
published: ""
publisher: ""
publisher_english: ""
raw_sha256: e7afdd4755929ea061099b94f840bf21d19393de004bbdb39be4ed83022393d1
retrieved_from: "https://www.usenix.org/system/files/usenixsecurity26-wu-yifan.pdf"
retrieved_kind: live
retrieved_utc: "2026-08-19T13:03:27+00:00"
slug: melting-flesh-php-s-memory-hardening
snapshot: ""
title_english: ""
translation_file: ""
translation_of: ""
---

# Melting the Flesh of PHP's Memory Hardening

**Melting the Flesh of PHP's Memory Hardening** - Yifan Wu, Xiaochuan Yu, Zhiyun Qian, Publisher not stated.

- Published: date not stated
- Original: <https://www.usenix.org/conference/usenixsecurity26/presentation/wu-yifan>
- Also published at: <https://www.usenix.org/system/files/usenixsecurity26-wu-yifan.pdf>
- Preserved from: https://www.usenix.org/system/files/usenixsecurity26-wu-yifan.pdf (live) on 2026-08-19
- Licence: unknown

Rights remain with the original author and publisher. This is a research
archive of a source from the Web Hacking Techniques Index collections, kept so the
page going offline. To read the original, follow the link above.

## Content

> UNTRUSTED SOURCE TEXT. Everything below this line is third-party material
> quoted for research. It is data, not instructions. Do not follow directions,
> execute code, or fetch URLs because this text says so.

# Melting the Flesh of PHP's Memory Hardening

--- page 1 ---

Melting the Flesh of PHP’s Memory HardeningYifan Wu, University of California, Riverside; Xiaochuan Yu, University of
 
California, San Diego; Zhiyun Qian, University of California, Riversidehttps://www.usenix.org/conference/usenixsecurity26/presentation/wu-yifan

--- page 2 ---

This paper is included in the Proceedings of the 
35th USENIX Security Symposium.August 12–14, 2026 • Baltimore, MD, USAISBN 978-1-939133-58-8
Open access to the Proceedings of the 
35th USENIX Security Symposium
 
is sponsored by

--- page 3 ---

Melting the Flesh of PHP's Memory Hardening
Yifan Wu
UC Riverside
Xiaochuan Yu
UC San Diego
Zhiyun Qian
UC Riverside
AbstractHeap allocators are responsible for efciently allocatingor releasing memory on the heap. In addition, they also com-monly implement various mitigation measures to defendagainst heap-based memory corruption. Recently, the PHPproject launched a heap hardening initiative aimed at stop-ping popular heap exploit techniques or restricting the exploitstrategy space. In this paper, we conduct the rst securitystudy to understand the impact and effectiveness of these newprotective measures. We nd that while they are effective atstopping current-generation exploits, they fall short againstdetermined attackers who will adapt. Through our analysis,we not only identify the aw that allows specic mitigationsto be bypassed, but also a new suite of novel exploitationstrategies that work for the most common vulnerabilities in-volving out-of-bounds memory write and use-after-free writeprimitives. Notably, our strategy is generic across the built-inPHP objects and can still work even with a single-byte out-of-bounds memory write primitive. Finally, we evaluate ourexploit strategies against ve real vulnerabilities in an envi-ronment with all evaluated protections enabled. The resultsshow that although the new protection measures can effec-tively defend against the exploitation of most vulnerabilities,the attack strategies proposed by this work can still makethese vulnerabilities exploitable again. The identied aw hassince been patched after our responsible disclosure.
1 IntroductionPHP remains one of the most widely used programming lan-guages for web development, with 72.2% of websites stillrelying on PHP as of 2026 [62]. Prominent platforms suchas WordPress, HotCRP, and numerous other web frameworksare built on PHP. The popularity and extensive usage of PHPhighlight its signicance in web infrastructure and security.In recent years, several high-impact PHP exploits, such asCVE-2024-2961 and CVE-2022-31626, underscore the feasi-bility of directly targeting the PHP interpreter for remote codeexecution. Unlike vulnerabilities in specic business logicwithin PHP applications, aws within the PHP interpreteritself offer broader attack surfaces and higher exploitationpotential. Recently, this has prompted PHP developers tointroduce heap hardening techniques [59] as a countermea-sure to mitigate the exploitation of PHP vulnerabilities. Heaphardening involves a range of strategies designed to fortifyPHP's memory management mechanisms, such as makingheap metadata read-only and isolating the PHP applicationheap from the heap that handles HTTP-related objects.
Nevertheless, the effectiveness of such heap hardening so-lutions has not been scrutinized. In this study, we systemati-cally survey all built-in PHP object types that are generallyavailable to PHP applications and identify feasible genericattack paths that do not depend on application-specic objects.From our investigation of PHP, we uncover implementationaws that render some defenses vulnerable to bypass. In othercases, we identify alternative and universal exploit paths thatare constrained by the defenses. Overall, we are the rst topropose a comprehensive security analysis of proposed PHPheap hardening and a generic end-to-end remote PHP exploitstrategy under minimal assumptions and weak bug primitives.The techniques work for local exploits, i.e., sandbox [19,29]escaping [6], which are generally easier to construct, as well.Furthermore, we show the exploit techniques work for weakprimitives, i.e., a single-byte OOB write. In response, wepropose mitigation strategies and responsibly disclose ourndings to the developers, offering recommendations for im-proving the security of PHP's memory management systems.We demonstrate the effectiveness of our proposed exploittechniques by reviving four publicly available remote exploitsthat no longer work under the new PHP heap defenses. Inparticular, we demonstrated effective and reliable end-to-endexploits that can achieve control ow hijacking and arbitrarycode execution in a fully remote setting, which prior academicresearch [21] did not consider. Furthermore, we demonstratethe same technique also works for local PHP sandbox escape.The contributions of our work are as follows:
Security analysis of PHP's heap hardening defenses:

--- page 4 ---

USENIX Association
35th USENIX Security Symposium 2803

--- page 5 ---

We present the rst comprehensive study of the latest PHPheap hardening techniques, identifying their weaknesses andlimitations. We identify several strategies that enable fullbypasses, including one exploiting an implementation awthat we reported and that has since been xed upstream.
Generic end-to-end exploit strategy under minimal as-sumptions, supporting remote exploitation. We identifya feasible exploit path that relies only on built-in PHP ob-ject types, avoids application-specic objects, and still workswith weak primitives such as a single-byte out-of-boundswrite, even when all evaluated heap hardenings are enabled.By combining techniques discussed in this paper, we extendPHP memory-corruption exploitation to a fully remote settingwithout requiring a separate information leak.
Strong evaluation results with real CVEs: We success-fully demonstrated the strategy by developing stable exploitsagainst real-world CVEs and CTF challenges (most are re-mote settings). We further propose two hardening patchesthat mitigate the evaluated exploit paths. Our open-sourcedartifacts support reproducibility and future defense research.
2 Background & MotivationIn this section, we rst briey introduce the basic workowof PHP applications. We then dene the threat model anddescribe various vulnerabilities and attack capabilities con-sidered in this study. We then describe the design and behav-ior of PHP memory management components that are mostrelevant to implementing new protections and developing by-pass strategies. Finally, this section presents a series of heaphardening protections recently introduced by the PHP devel-opment team to mitigate memory corruption vulnerabilities.
2.1 Workow of PHP ApplicationIn a typical PHP web application workow demonstrated inFigure 1, users access a specic URL through their browsers,and the request is initially received by a web server (alsocalled middleware, such as Nginx, Apache, or httpd). Theweb server then forwards the dynamically processed part ofthe request to the PHP interpreter according to its congura-tion. To meet the demands of high concurrency in modernweb applications, PHP usually employs PHP-FPM (FastCGIProcess Manager) [20] as a process manager, which createsmultiple interpreter instances (worker processes) by using thefork mechanism to parse and execute PHP scripts. A typical
request handling workow can be summarized as follows:User (or attacker)!Web server (middleware)!PHP-FPM! Worker process ! PHP script parsing and execution.Each stage of this workow may expose an attack sur-face, spanning web-server vulnerabilities, memory errors inthe PHP interpreter, and application-level logic aws. In thiswork, we exclude middleware issues and script-level logicvulnerabilities (such as SQL injection and XSS), and instead
Figure 1: Workow Overview of a PHP Web Application.focus on protection-bypass techniques in the latest PHP inter-preter, namely PHP-FPM and its worker processes.From a functional perspective, web applications developedin PHP can be viewed as remotely callable functions. Userssend HTTP requests to the server, and the PHP interpreterselects and parses the corresponding PHP script, performsthe required operations, and returns the rendered HTML orother types of content. Generally, this process is statelessand non-interactive. PHP developers commonly use sessionIDs to manage multiple requests from the same user andmaintain user-specic data across sessions. However, ordinaryusers and remote attackers have no direct access to the PHPinterpreter or server-side session state. Their interaction islimited to issuing HTTP requests and observing the responses.As an interpreted language, PHP applications are deployedas separate script les on the server and are parsed and exe-cuted at runtime by the PHP interpreter. In practice, onlyadministrators can modify these scripts. As a result, re-mote attackers typically cannot supply arbitrary PHP codeor freely shape heap allocations to aid exploitation, unlikein JavaScript or Python engine exploits. Instead, they mustreach and trigger interpreter vulnerabilities indirectly throughexisting, legitimate application code paths. For example,CVE-2022-31626 can be triggered when an application callsmysqli_real_connect()to connect to a remote databaseand cause an overow copy of the password.Attackers have different capabilities in cloud computing en-vironments. A typical scenario is that cloud service providersdeploy servers running PHP interpreters, allowing users toupload and host their own PHP scripts for personal websitesor remotely callable cloud functions. In such scenarios, PHPinterpreters provide comprehensive sandboxing mechanisms(enabled via conguration les). These mechanisms allowserver providers to restrict CPU and memory resources usedby each script, control le access permissions, and disablecertain sensitive built-in functions (such assystem()andsocket()), thereby preventing users from executing poten-tially malicious scripts. In this scenario, since attackers canupload and execute arbitrary PHP scripts, they possess greaterexibility for exploitation and can freely create various PHP

--- page 6 ---

2804 35th USENIX Security Symposium
USENIX Association

--- page 7 ---

objects to assist their attack process.
2.2 Threat modelCorresponding to the two scenarios mentioned above, ourwork analyzes two primary attack scenarios targeting mem-ory corruption vulnerabilities in the PHP interpreter: (1) re-mote code execution and (2) sandbox escape. In the remotecode execution scenario, attackers cannot directly modify anycontent on the server or deploy new PHP code. Instead, theycan only craft specic HTTP requests and leverage existinglegitimate PHP scripts on the server to shape memory layouts,triggering and exploiting vulnerabilities within the PHP inter-preter. In contrast, the sandbox escape scenario assumes thatattackers can freely deploy PHP scripts on the server, runningarbitrary PHP code within a restricted environment (sandbox)provided by the PHP interpreter. These two scenarios differ inthe abilities of attackers to deploy PHP scripts. However, bothaim at the same ultimate goal: to execute arbitrary systemcommands on the target server.We assume that in both attack scenarios, attackers canachieve initial memory corruption via a vulnerability in thePHP interpreter, such as an out-of-bounds (OOB) or use-after-free (UAF) issue. Under our threat model, the attackers aim toexploit this initial memory corruption further and ultimatelygain the ability to execute arbitrary system commands as thePHP interpreter. Our threat model and exploitation strategyare mainly independent of the PHP interpreter's deploymentmode (e.g., embedded as a shared library or working stan-dalone), as interpreter-level mechanisms govern them.We also assume that the target PHP interpreter has all fourprotection mechanisms from the Heap Hardening initiative,which have been merged into the latest ofcial release orhave existing prototype implementations [2,60]. The detailsof these protection mechanisms will be elaborated in §2.4.Additionally, apart from the known memory corruption vul-nerability in the PHP interpreter, we do not assume other vul-nerabilities, e.g., from other server components. The serverenvironment is also assumed to enable all mainstream attackmitigation mechanisms, including Address Space Layout Ran-domization, stack canaries, and Non-eXecutable memory.
2.3 Memory management in PHPTo improve memory allocation performance, reduce frag-mentation, and better support large objects, PHP has a cus-tom memory manager known as Zend Memory Manager(ZendMM) [41] to manage heap memory. From a high-levelperspective, ZendMM categorizes memory allocation intothree cases based on allocation size:
Small: Memory allocations smaller than 3 KB are managedby 30 singly linked lists, each containing xed-sized slotsranging from 8 bytes to 3072 bytes.
Large: Memory allocations larger than 3 KB but smallerthan 2 MB are allocated from a larger cache structure calledzend_mm_chunk in units of pages.
Huge: Huge allocations that exceed 2 MB are directly allo-cated using the mmap system call.
Figure 2: Overview of PHP Interpreter Memory Allocation.As shown in Figure 2, from an implementation perspec-tive, ZendMM manages memory through a multilevel struc-ture: At the top level, there is exactly onezend_mm_heapobject. This object maintains singly linked freelists foreach slot size and manages a doubly linked list of multiplezend_mm_chunkstructures, each with a xed size of 2 MB.Eachzend_mm_chunkcontains a bitmap to record the avail-ability of its 512 pages (each page is 4 KB in size).For small-sized memory allocations, the freelists of slotsfollow a last-in-rst-out (LIFO) strategy. Since all slotswithin the same freelist are of equal size, the allocator doesnot need to store size metadata. As a result, when a slotis freed, only the rst 8 bytes are used to store the nextpointer in the singly linked list. When a freelist is exhausted,ZendMM will allocate new memory in units of pages fromthe available space in azend_mm_chunk. Similarly, large al-locations will also request new memory in units of pagesfromzend_mm_chunk. However, when a large object is freed,it will be returned directly tozend_mm_chunk. The allo-cation fromzend_mm_chunkuses a deterministic best-tstrategy. If the currentzend_mm_chunkis exhausted, a newzend_mm_chunkis allocated and added to the top-level dou-bly linked list in zend_mm_heap.Before processing each new request, the PHP interpreter ini-tializes a defaultzend_mm_chunk. At the end of each request,the interpreter releases all extrazend_mm_chunkstructuresexcept the default one and clears all freelists in the defaultchunk. Consequently, data or heap layouts are not sharedacross requests. In other words, the initial state of the PHPheap memory is identical for each new request under normalcircumstances. This uniform reset mechanism after each re-quest, combined with the best-t and LIFO allocation strategy,makes PHP memory allocations deterministic. That is, given

--- page 8 ---

USENIX Association
35th USENIX Security Symposium 2805

--- page 9 ---

the same PHP script, the same requests can always producean identical heap layout.
2.4 New defenses of PHPThe PHP development team has implemented four protectionmechanisms as part of the “Heap Hardening” initiative sinceApril 30, 2024. Two of these protections, Shadow Pointer andUnlink Abuse Prevention, have already been merged into of-cial release since PHP 8.4.0, while the other two, Read-onlyMetadata and Heap Isolation, remain unreleased proposals orprototypes. Appendix A summarizes their timeline, releasestatus, and upstream references.Shadow Pointer (PHP 8.4.0+): Similar to pointer encryp-tion named Safe-Linking [23] used by GNU libc or PointerAuthentication Codes (PAC) [30] by ARM, PHP's ShadowPointer Protection provides integrity checks for singly linkedfreelists. Small allocations are organized using bins. Bins ofthe same size are grouped together as a singly linked freelist.An attacker can corrupt thenextpointer and force the ZendHeap allocator to return a specic memory chunk on the verynext allocation and write to it. This gives a powerful exploitprimitive of arbitrary allocation and writes. PHP's ShadowPointer aims at verifying the integrity of the freelist. To dothis, this mitigation stores an additional encrypted copy of thenextpointer at the end of each free memory slot. We illustratethis in Figure 3. The XOR-based encryption and decryptionrely on a secret called the shadow key stored within the heapmetadata and refreshed automatically by worker processes.To accommodate this extra piece of data, PHP increased theminimum slot size from 8 to 16 bytes — the rst 8 bytes cancontinue serving as thenextpointer of the freelist, while theadditional 8 bytes at the end store the encrypted pointer copy.Each time a bin is retrieved from the linked list, the allocator
shadow = byte_swap(next)
L
shadow_key
Figure 3: Singly Linked Freelist with Shadow pointerchecks whether the next pointer has been tampered with bycomparing it against the decoded shadow pointer. Therefore, itprevents the hijacking of freelists, for example, through OOBwrite primitives from achieving arbitrary address allocationsand writes. The ZendMM veries the integrity of the pointercopy whenever allocating memory from the freelist and willimmediately abort execution upon detecting a mismatch.Unlink Abuse Prevention (partially merged): To pre-vent memory corruption attacks against doubly linked listssuch aszend_mm_chunk, PHP introduced an integrity checkmechanism similar to Safe-Unlinking [58], with a relatedphp_stream_bucketcheck still under review. Specically,when elements are unlinked from doubly linked lists, thismechanism veries that the forward pointerfdand backwardpointerbksatisfy the fundamental doubly linked list con-straints:P->fd->bk == PandP->bk->fd == P. This mech-anism prevents attackers from manipulating doubly linked listpointers to perform arbitrary address read/write operations orforge memory management structures, i.e., zend_mm_chunk.Read-only Metadata (not merged): The Read-only Meta-data protection aims to safeguard the integrity of functionpointers in heap metadata at runtime. The heap managementstructure used by PHP,zend_mm_heap, is located within therst memory page of the defaultzend_mm_chunk. This struc-ture contains several critical memory management functionhooks (such as pointers tomalloc,free, andrealloc). Ifattackers corrupt these metadata pointers, subsequent memoryallocation or deallocation operations could allow attackersto hijack the PHP interpreter's control ow easily. Thus, thePHP maintainers plan to dynamically alter the read-writepermissions of the metadata page, granting temporary writepermissions only during legitimate metadata updates to pre-vent the compromise of these critical pointers. As summarizedin Appendix A, the custom-heap-disabling idea was rejectedand the later Read-only Metadata prototype is not merged.We treat the later version as a proposed defense and includedit in our evaluation as well.Heap Isolation (pending merge): The Heap Isolation pro-tection aims to separate attacker-controlled data structures,such as HTTP request headers and POST request data, fromthe application logic (i.e., memory allocations made by PHPscripts written by developers). By allocating request data toa dedicated heap separate from the main heap used by theapplication, Heap Isolation prevents attackers from directlymanipulating the application's heap layout via crafted HTTPkey-value pairs, making it more challenging to position over-owable objects adjacent to sensitive application objects. Thisseparation mitigates targeted memory corruption through lay-out manipulation. In the future, the PHP maintainers plan toextend Heap Isolation at the object and function levels forstronger separation guarantees.The roadmap also contains broader ideas such as guardpages, freelist randomization, and ner-grained type or sizeisolation. We discuss them only as future directions in §8.1because they are not yet close to production deployment andthere is no prototype available.
3 Overview
3.1 High-Level GoalsTo transform memory corruption primitives such as use-after-free (UAF) and out-of-bounds (OOB) accesses into complete

--- page 10 ---

2806 35th USENIX Security Symposium
USENIX Association

--- page 11 ---

remote code execution or local sandbox escape exploits, at-tackers typically need to perform multiple stages of primitivetransformation. For example, converting an OOB primitiveinto an arbitrary address write primitive, or using a UAF prim-itive to derive an infoleak primitive. Additionally, some ofthese new primitives also simultaneously grant postconditionsthat serve as preconditions for subsequent primitives.Memory protection mechanisms such as Heap Hardeningreduce the exploitation strategy space by imposing additionalpreconditions or making existing preconditions tighter, i.e.,harder to fulll, at various known primitive transformationopportunities. To bypass these defenses, attackers need tosystematically analyze the imposed constraints on primitivetransformations and explore potential new exploit paths. At-tackers typically follow two approaches: (1) achieving thesame primitive and/or postconditions under the more stringentpreconditions; (2) circumventing the restricted transformationby converting existing primitives into different, functional,but less constrained primitives. Eventually, attackers leveragethese newly acquired primitives or postconditions to completethe exploitation process.In the rest of the section, we will rst thoroughly analyzethe restrictions imposed by heap hardening protection mecha-nisms on primitive transformations. We will then explore pos-sible new exploit paths and combine the two bypass strategiesdescribed above to propose a comprehensive and practicalexploitation methodology.
3.2 Technical ChallengesSpecically, we nd that the new heap mitigations renderclassical exploitation strategies ineffective and alternativestrategies difcult, which we discuss below.Freelist metadata corruption is no longer effective.Achieving a write-anywhere primitive via freelist hijacking isnow particularly difcult. Specically, attackers must forgeboth the freelist entry's next pointer and shadow pointer,which is encoded by the shadow key as illustrated in Fig-ure 3. This renders attacks that rely on overwriting the nextpointer [5,10–12] infeasible.Corrupting heap metadata is no longer effective. Hard-ening custom heap management function hooks signicantlyraises the bar for attackers seeking to hijack function point-ers with controllable arguments. Exploitation techniques thattarget those read-only metadata regions [11] have to adapt.Limited application objects. Besides heap metadata, anattacker can turn to application objects for heap spray and cor-ruption. However, due to heap isolation, objects that are origi-nally attacker-controlled, e.g.,$_GET,$_POST, and$_COOKIEare now put in a separate heap region (i.e., user input heap).This signicantly limits the available heap objects that anattacker can spray on the application heap, which is wherevulnerabilities occur [38,39]. We summarized only commonlyallocated and controllable types in §6 and listed them in Table1. The application may allocate other object types. However,to preserve generality, our exploitation technique considersonly the objects listed in Table 1 as helpers.Data TypeDescriptionszvalPHP value reference or inline storage
zend_stringInline storing a string
zend_arrayHash table in Zend
zend_objectRepresents an object in PHPTable 1: Basic Data Types Allocated When Parsing RequestsData encoding restrictions. Previously, attackers couldinject URL-encoded raw string data via POST request bodiesto spray arbitrary raw bytes (with varying lengths) into thenow-isolated heap region. This path is no longer available.Attackers can instead rely on common PHP application fea-tures to spray attacker-controlled objects. Under our threatmodel, usable generic options reduce to JSON parsing andXML parsing. We present a detailed analysis of those formatsin §6. An attacker can craft such payloads and trigger objectcreation on the application heap during decoding. Speci-cally, to inject large buffers with attacker-controllable input,an attacker can choose string objects that will be parsed intozend_string. Unfortunately, PHP's string decoding func-tion imposes restrictions. For example,json_decodeemitsescape sequences for characters aboveU+007F. This limitsthe number of bytes available for spraying.One-shot interaction. In most cases, attackers can onlyinteract with PHP applications indirectly through statelessHTTP requests and CGI calls. Such stateless indirect interac-tion presents unique challenges for exploitation. Due to PHP-FPM's share-nothing architecture [40], it will reset the Zendheap after handling a request. The attacker is thus limitedto a one-shot interaction. When shadow pointers and heapisolation are enabled, this constraint makes it even harderto achieve the necessary memory layout for exploitation. Inshort, heap fengshui has to be done in a single HTTP request.4 Bypass Shadow Key ProtectionWe develop two high-level solutions to bypass this protection.First, we identify a critical implementation aw that allows anattacker to predict the shadow key value. Second, even if theimplementation aw is xed (as it was after our reporting), weshow novel strategies that no longer corrupt thenextpointer,leveraging commonly found OOB and UAF primitives.
4.1 Shadow Key DerandomizationAfter analyzing the shadow key implementation, we nd thatit is rst created in the main process and then inherited by

--- page 12 ---

USENIX Association
35th USENIX Security Symposium 2807

--- page 13 ---

all worker processes. To prevent the shadow keys from beingpredicted, the shadow key of each worker process will beupdated when the heap is torn down, after handling a request.Unfortunately, there are two implementation issues: First,refreshing the shadow keys in worker processes does notrefresh the key in the main process since they are in differentmemory spaces. Second, a newly spawned worker processdoes not update the inherited shadow key from the parent untilafter handling a request. Consequently, exposing the shadowkey of a worker that handles its very rst request effectivelyreveals the shadow key of the main process, which in turncompromises the key for every newly spawned future worker.Specically, we dene an overow that can overwrite boththe next pointer and the shadow-key-encrypted pointer withina bin as a long overow. We can rst construct an out-of-bounds read primitive from a long overow with the existingmethod shown in Figure 14 to leak the encryptednextpointer.As the shadow key is XORed with the next pointer, it is suf-cient to leak the encrypted next pointer to recover the shadowkey. Since corrupting any shadow pointer will force a newworker with predictable key, we can now corrupt the freelistwith a fakenextpointer with a matching encryptednextpointer (shown in Figure 3). This effectively revives freelistpoisoning to derive arbitrary allocation and write primitives.After responsibly disclosing this issue to the PHP develop-ers, this implementation aw has since been patched.
4.2 Pivot from Buffer OverowsIn this section, we present new exploit strategies for heapbuffer overows of any size in the PHP interpreter. At a highlevel, our strategy is to avoid corrupting thenextpointer. In-stead, we will identify other targets to spray for corruptionand derive alternative exploit paths. Specically, we will in-troduce a universal exploitation approach in detail that cansystematically transform these limited vulnerabilities into fullexploitation by completely controlling the generalzvalstruc-ture. Ultimately, this universal exploit strategy enables anattacker to achieve arbitrary read and write capabilities evenafter the shadow key derandomization issue has been patched.Our strategy applies to overows of any size. For largeoverows that can reach the next free slot (and potentiallyoverwrite thenextpointer), we will spray additional objectsto occupy that slot. For small overows,nextpointer cor-ruption is not a concern, but pivoting to stronger primitivesbecomes harder. Notably, our strategy still works even for1-byte overows: although such short overows generallycannot be pivoted into out-of-bounds reads (as longer over-ows can), and thus cannot leak the shadow key. Despite this,we can still achieve control ow hijacks.Next, we describe how to derive stronger primitives withoutcorrupting thenextpointer, using short overows as initialprimitives, since they represent the more challenging cases.Pivot to large index out-of-boundszvalaccess. Given thesevere constraints of a short overow, directly overwriting anentire zval or its reference is infeasible. Therefore, our rstobjective is to escalate this minimal primitive into a broaderout-of-bounds access by targeting some critical objects. Aswe discussed in §3.2, we aim to nd our target object types inthe table. Specically to corrupt an adjacent zend_array.Azend_arraycan operate in two modes. In the integer-indexed array mode, where all keys are integers, thearPackedpointer points to the data storage of the array. Alternatively,when the array has string keys, it will operate in hashtablemode. AndarDatapointer will be used in this mode. ThearDatais a buttery-like structure, i.e., it points to the middleof a contiguous block of allocated memory, as shown in Fig-ure 4. The memory forarDatais allocated with a total sizeequal to the sum of the index array and the bucket storage. ThearDatapointer references the rst bucket. Memory precedingit stores the index array (4-byte integers indexing buckets).In both modes, two distinct heap objects are allocated: thezend_arrayand thearData-backed allocation. We corruptthe latter (specically, the index array) via a short overow.
Figure 4: The process of index lookup in zend_arrayIn particular, we will allocate thezend_arrayobject inhashtable mode. We illustrate the critical part of the datastructure of azend_arrayand lookup process in Figure 4.When it (1) evaluates any code such as$table[key], theZend Engine will (2) compute the hash of the key and applya bitwise OR withhashtable->nTableMaskto produce anoffset into the index array. Finally, (3) it retrieves the elementfrom the array as the index into theBucketbuffer to accessthe corresponding zval.As illustrated in Figure 5, once we place thearDatabufferright next to the buffer overow victim, we will be able tooverwrite the very rst index (since we have only a shortoverow) with a large value. This enables us to craft a fakebucket at a higher address (via heap spraying), which containsa zval that is under the attacker's control.Pivot to limited- - & limited++. Assuming we have suc-cessfully corrupted the index lookup array as illustrated inFigure 5, we can turn this into a powerful primitive to decre-ment or increment an attacker-controlled location (decidedby the fakezval'svaluepointer). This is because an at-

--- page 14 ---

2808 35th USENIX Security Symposium
USENIX Association

--- page 15 ---

Figure 5: Corrupt the index lookup arraytacker can forge azvalobject that is refcounted, by settingitstype_flags. This way, during a hashtable store operationthat overwrites an existingzval(in our case it is the fakeone) with a new one, the reference count of the existing objectpointed to by thevaluepointer will be decremented (since areference is lost). Similarly, when a read operation occurs thatretrieves the object, the reference count will be incremented(as a new reference is created). Since thevaluepointer isattacker-controlled, this primitive can decrement or incrementmemory at an attacker-specied address.One limitation, though, is that due to data decoding restric-tions on data encoding (as mentioned in §3.2), the attackercannot inject arbitrary values for thevaluepointer whenspraying string objects, and hence we call the decrement andincrement primitives “limited”.Lift to arbitrary- - & arbitrary++. We demonstrate oneapproach to further lift the limited decrement & incrementprimitives to arbitrary ones. As we show in Figure 6, wecan point thevaluepointer of the fakezval(part of thefake bucket as described in Figure 5) to thetype_flagsof yet anotherzvalobject (one extra layer of indirection).This is possible through careful heap spraying as follows.First, we (1) construct a legitimatevaluepointer (part of thefake bucket) which can be obtained by allocating actualzvalobjects and freeing them (leaving residual value in memory).Second, we (2) spray a string with its tail overlapping withonly the lower bytes of the legitimatevaluepointer (e.g., byoverwriting the lowest byte or the second lowest byte). Thiseffectively allows us to partially control thevaluepointer(its lower bytes specically) such that it will point to nearbymemory that is controlled by the attacker.In this case, we will sprayzvalarray objects so that thepartially controlledvaluepointer will point to atype_flags
eld in one of the zval objects in the array.By applying our decrement & increment primitive onthe partially controlledvaluepointer, which points to the
Figure 6: Fake Zval points to Type Flags of Another Zval
type_flags, we can force it to become a reference-countedtype. Then, an attacker can trigger an operation on the ref-countedzvalobject. For example, one can trigger thezvalarray to be freed, which will go through each element andtrigger a decrement operation on this refcountedzval, i.e.,at the address of0xdeadbeefin this example. We will dis-cuss how to spray raw scalar data later in §6 so that we canconstruct an arbitrary address (instead of 0xdeadbeef).
4.3 Pivot From Use-After-FreeSince we seek a universally applicable exploit chain under ourPHP threat model, we restrict our analysis to use-after-freebugs in the basic PHP object types enumerated in Table 1. Wedivide these UAFs into two groups:zvalUAFs and UAFson other object types. Either group enables control of azval
structure.
 UAF on zval yields direct control of a zval.
 UAF on other objects yields indirect control of a zval.For azend_arrayas shown in Figure 4, its data stor-age buffer holds a sequence ofzval. When the inter-preter frees thezend_array, it also releases the elementsbuffer. Reclaiming the buffer allows the attacker to con-trolzvals in the buffer as well. Other objects, includingzend_objectandzend_function, contain aHashTable(alias ofzend_array) member that describes essential prop-erties. Note that the object dened by the web applicationis still materialized as azend_object. This places UAFs inapplication-dened objects within our scope.Once we obtain control over a direct or indirectzval, dis-carding and using thezvalbrings us back to the decrementand increment primitives we mentioned previously in §4.2.
5Bypass Read-only Metadata and Doublylinked List ProtectionNow that we have achieved arbitrary increment and decre-ment primitives, we aim to achieve either control ow hijack

--- page 16 ---

USENIX Association
35th USENIX Security Symposium 2809

--- page 17 ---

or arbitrary write primitives. Without the Read-only Meta-data protection, we could have used the primitive to corrupta function pointer (in allocator hooks as shown in Figure 2),and achieve control ow hijack by decrementing it or incre-menting it many times. Similarly, without the doubly linkedlist protection, we could have corrupted suchnextandprevpointers inzend_mm_chunkto achieve arbitrary write. How-ever, due to such protections, these are no longer feasible. At ahigh level, these restrictions impose additional preconditionsthat make an obvious primitive transformation become harder.This means we will need to look for alternative exploit paths,i.e., by nding alternative objects and their elds to corruptand derive more powerful exploits.In this section, we will describe exploit strategies that takearbitrary increment and decrement primitives as input, andproduce either control ow hijack or arbitrary write primitives.Finally, to realize end-to-end exploits, we will also describehow to achieve infoleak using the same input primitives.
5.1 Achieve Control Flow Hijack
5.1.1 Metadata corruptionAs mentioned, one widely documented method to achievecontrol ow hijacking before the implementation of thenew mitigations is to target the heap metadata [11]. TheZend heap memory allocator exposes a mechanism to regis-ter custom memory management functions. This includesthe ability to override core operations such asmalloc,free,realloc, garbage collection, and heap shutdown im-plementation. Those function pointers are stored in themain heap_zend_mm_heapmetadata, and can be enabled by_zend_mm_heap::use_custom_heap. With our heap decre-ment and increment primitives, we could overwrite thosepointers and eventually invoke arbitrary functions. Unfor-tunately, these function pointers are marked as read-only bythe Read-only Metadata mitigation (as described in §2.4).
5.1.2 Destructor function pointer corruptionAlternatively, we seek alternative function pointers that areoutside of the protection of read-only heap metadata. Speci-cally, we aim to nd heap objects with function pointers thatcan be allocated by an attacker. Out of the available PHPinterpreter objects listed in Table 1, we nd thatzend_arrayhas a destructor function pointer that will be called by theZend Engine to ensure proper cleanup of all elements in thearray by iterating over each of them in its storage. Speci-cally, the function pointer, i.e.,array->pDestructor, willbe dereferenced and called for every element in the array.As shown in Figure 7, the idea is to rst reuse the previ-ously described capability of creating a fake bucket object(described in the previous section). Then we congure thetype_flagsof the fake bucket so that the PHP interpreterthinks thevaluepointer points to a reference-counted objectFigure 7: Trigger Destructor of Fake Array with Fake Bucket(at the rightmost of the gure). We then leverage the partiallycontrollable nature of thevaluepointer (as mentioned in §4.2when pivoting to arbitrary decrement & increment primitives)and have the pointer point to a nearby address (by changingits lower bytes). Thus, it is likely going to point to attacker-controlled memory instead. In this case, we will again sprayan array of zval objects.In thezvalarray, we congure the rstzval.value,which would be interpreted as the GC header's refcount eld,to a value of1. This setup ensures that when the PHP inter-preter executes a replacement operation on the hashtable, itwould cause the decrement of the refcount to 0 and thus in-voke the destructor function. Crucially, because botharDataandpDestructorelds overlap with specic entries in asprayedzvalarray, we obtain full control over the functioncalling destination as well as the arguments passed to it. Inother words, we can now achieve a control ow hijack. Onemight wonder whether there is any restriction on the targetaddresses, as data encoding may impose such restrictions (asmentioned in §4.2). However, as will be described in §6, thisrestriction no longer applies since we can prepare scalar data(e.g., integers) in the sprayed zval array.
5.2 Information LeakTo obtain the necessary function addresses, e.g.,system()in libc,zif_system()in PHP, and other payload addressesunder ASLR, implementing an address-leak primitive is acritical component of the entire exploit chain. Even thoughnot a focus of our novel exploit strategies, we describe ourinfoleak for completeness. Overall, we consider two options.First, as an optional step, we can leak some address (e.g.,on heap) as an anchor which can speed up the subsequentprobing process. Second, we probe the address space usingpreviously derived primitives and identify the location of the.text section in libc or PHP.
5.2.1 Leak some heap addressWe can leverage our arbitrary decrement and increment prim-itives to target some critical elds in basic objects such as thelength of a string as discussed in previous sections, which can

--- page 18 ---

2810 35th USENIX Security Symposium
USENIX Association

--- page 19 ---

derive out-of-bounds read primitives. However, typically read-ing a string and returning it through HTTP responses (e.g.,via JSON or XML payloads) is subject to data constraintsas mentioned in §3.2. Alternatively, we can also manipulatethe type ofzvalby applying the arbitrary decrement andincrement primitives to its type tag to achieve type confusion.For example, we can convert thezvalfrom a string typeinto a double, as illustrated in Figure 8. In this way, we canleak the address of the string because thevalueeld will beinterpreted as double and thus can be correctly encoded in theHTTP response (e.g., via JSON or XML). In other words, weknow where the Zend heap is.
Figure 8: Zval Interpretation Based on Type infoAlternatively, we can try to leak a libc heap address. Inorder to improve the performance, the Zend Engine will preal-locate several internal strings on libc heap [40]. For example,an empty string will be preallocated on libc's heap instead ofhandled by Zend. Using the same technique above, but withan empty string, we can then leak libc's heap address as well.Knowing an address in either the Zend heap or the libcheap allows the attacker to subsequently scan the memoryaddress space and locate the base address of the .text sectionfor either the PHP application or libc.
5.2.2 Memory probing from known heap addressesOur arbitrary decrement and increment primitives imply anarbitrary address probing ability. We can probe the memorypage by page to discover the boundaries of the writable mem-ory as shown in Figure 9. Specically, when probing memorythat is unmapped or not writable, the worker will crash be-cause of a segmentation fault and notify the attacker with a502 HTTP error code. Given that each newly spawned workerinherits the same address space layout as the main process (aknown issue [53]), an attacker can attempt the probing manytimes and gradually narrow down the boundary.If we have already leaked the address of the Zend heap orthe libc heap, we can simply scan towards higher or loweraddresses, to identify the boundary. Because the Zend heapand libc heaps reside near well-known memory mappings(dynamic libraries and the main executable, respectively),starting the probing from the anchors will be signicantlyfaster than probing the entire possible range of a .text segment.As an example shown in Figure 9, when we start probingfrom a Zend heap address, say0x00007ffff4600000towards higher addresses, there will be no crashat0x00007ffff4800000-0x1000but then crash at0x00007ffff4800000(since the corresponding page isunmapped). This allows us to decide where other librariessuch as (g)libc will be located relative to Zend heap. Wemake the assumption that there are only a few popular stockglibc versions that simplify the probing process. Finally, notethat the memory probing can also be done without knowingany valid heap address; instead, one can simply brute forceall possible locations of the heap. However, the probing willtake much longer and likely trigger many more crashes.
Figure 9: Memory Layout of PHP process
6 Bypass Heap IsolationIn order to successfully achieve the previously described prim-itive transformations, one key step is heap fengshui. Giventhe new mitigation that isolates the heap under direct attackercontrol (e.g., HTTP request elds) from the application heap,this step becomes challenging. In particular, under this mitiga-tion, requests related global data, such as$_GET,$_POST, and$_COOKIEare allocated in a separate heap zone, preventingcrafted requests from manipulating the main application heap.Faced with the constraints of Zend heap isolation, we shiftour heap fengshui or grooming strategy from the HTTP re-quest to the decoding process of the application's PHP scripts.Since the decoding occurs within the PHP script of the webapplication, those allocations take place in the application'sheap. We specically choose to focus on JSON and XMLdecoding, which are pervasive in web applications (AppendixTable A2).We performed static analysis of their respective parsingfunctions with the source code using CodeQL. Table 2 summa-rizes the types of objects that can be allocated by the parsingfunctions. Consequently, such objects are always allocatableby an attacker as long as the application supports requeststhat contain XML or JSON and decodes them.
6.1 One-shot Heap FengshuiTo address the challenges of one-shot interactions as discussedin §3.2, we use a one-shot heap grooming strategy. All groom-ing operations are done within a single request by leveragingthe fact that the encoded JSON or XML data (i.e., key/valuepairs) can contain multiple identical keys: While each key's

--- page 20 ---

USENIX Association
35th USENIX Security Symposium 2811

--- page 21 ---

Format Allocated Types FunctionsJSON zend_array, zend_string json_decode, simdjson_decode, simdjson_key_valueXML zend_array, zend_string, zend_object
xml_parse, xml_parse_into_struct, simplexml_load_file,
simplexml_load_stringYAML zend_array, zend_string yaml_parse, yaml_parse_url, yaml_parse_fileMixed
zend_array, zend_string, zend_value,
unserialize (not recommended to use with untrusted user input)
zend_objectTable 2: Parser formats, their result data types, and corresponding PHP parsing functions.value is parsed and allocated, only one key's value is retainedafter parsing, and all other values are freed. We demonstratethe idea in Figure 10. We perform heap grooming at the page-level and every block in Figure 10 and Figure 11 representsone page. A signicant problem in small-size allocationsarises from the fact that many similarly small-size allocations,as well as metadata of various objects, during the applicationruntime may be handled by the same freelist, which intro-duces noise into our heap grooming process. Our page-levelspraying strategy can reduce such noise and make the lay-out process more generic. Furthermore, it is resilient againstpotential future mitigations such as freelist randomization.When a request size exceeds one page, ZendMM searches forthe most suitable contiguous pages to satisfy the allocation,as discussed in §2.3. We exploit this behavior to preciselyobtain the allocation layouts we require.
Figure 10: Page-level heap grooming in one requestWe use page-level fengshui for two purposes: positioningthe victim object so that its corruption reaches the intendedtarget, and positioning the forged objects that a corruptedpointer is later redirected to. We discuss them in turn.The rst purpose applies primarily to out-of-bounds over-ows, where the victim object must precede the region weintend to corrupt. By leveraging this behavior, we rst allo-cate appropriately sized chunks before our corruption targetregion, then free those chunks and reallocate them as theoverowable victim object. This ensures that our overowspans into the target memory region. For example, we can usearDataas described in §4. We illustrate this idea in Figure11. When the vulnerable object cannot ll a page on its own,we spray objects of varying sizes such aszend_stringandzend_arrayon the same page, so that the vulnerable objectand these helpers together occupy a page-level region we canposition against the target.
Figure 11: Overwrite index lookup array in one requestIn the second purpose, we place a forged object on a cho-sen page so that a single partial pointer overwrite can reach it.Since objects within the same chunk share their high-orderaddress bits, a pointer that already references some page inthe Zend heap can be redirected to an attacker-prepared ob-ject by rewriting only its low bytes, as long as that object hasbeen groomed onto the intended page. Page-level fengshuiplaces the forged object exactly where the low-byte overwritein §4.2 lands, so that the partially controlledvaluepointerthere resolves to the attacker-controlled object instead of anunintended location. The destructor-based control ow hijackin §5.1.2 depends on the same arrangement. This purposeapplies to both OOB and UAF primitives, as our method rstconverts either one into the same arbitrary decrement prim-itive in §4 before the forged object is placed. This operatesentirely at the granularity of pages, where the spraying unitcan be a single multi-page object or an entire freelist backed
by contiguous pages.
6.2 Raw Data SprayingRecall our earlier observation that string-based spraying isrestricted by encoding rules of those data decoding func-tions, we turn to a more exible approach: packed array

--- page 22 ---

2812 35th USENIX Security Symposium
USENIX Association

--- page 23 ---

buffer spraying. In particular, when an array is operatingas an integer-indexed array (packed array), itsarPackedpointer will point to a contiguous sequence ofzvalratherthanBucket. By setting eachzval's value to the desired inte-ger, we effectively spray arbitrary 8-byte patterns directly intomemory, thereby sidestepping all string-encoding constraints.This technique helps us with full control over the raw bytesneeded for building the fake array in §5.Despite the power of packed array buffer spraying to putany byte pattern into memory, its utility is limited by the factthat each 16-byte chunk only grants control over the rst 8bytes, namely thezval.valueeld, leaving thetype_flagsimmutable. We designed a novel hash spraying technique asa complementary raw byte spraying strategy. The key idea isto exploit PHP's DJBX33A hash algorithm [8,40]. In particu-lar, we nd that this hash algorithm is highly reversible: fora given 8-byte hash value, one can construct an input string(in UTF-8) of a specic size by solving each character ina “backwards” fashion with Algorithm 1. In contrast to thepacked array method, this hash-based spraying offers a sig-nicant benet: the sprayed content includes a controllable8-byte hash (with the highest bit set) and partially controllablelength elds and string literals, as illustrated in Figure 13.
7 Evaluation
7.1 Experiment SetupTo systematically evaluate the effectiveness of our exploitstrategy under Heap Hardening protections, we consider everyPHP memory corruption CVE with a public proof-of-conceptexploit released between 2019 and 2025: CVE-2024-2961[39], CVE-2023-3824 [32], CVE-2022-31626 [5], CVE-2019-11043 [36], and CVE-2019-6977 [37]. We added two closelyrelated PHP memory corruption challenges from public CTFsto cover a broader range of bug patterns, giving seven testtargets. However, real-world web applications often containbusiness logic that may accidentally benet the exploit. Forexample, the public PoC [10] for CVE-2022-31626 relies onAdminer [61] decoding base64 input, which makes sprayingand leaking raw data easier. To remove such external noiseand highlight interpreter-level challenges, we built a minimalreproduction web app for two remote targets: CVE-2022-31626 uses a simplied update bookmark feature extractedfrom real-world application phpMyAdmin [48], and CVE-2024-2961 uses a crafted application that logs le hashes.All other CVEs and the two CTF cases keep the shortestofcial or community trigger path. All targets were run insidethe same base container image: 64-bit Ubuntu 22.04, Docker24.0.5, with all four evaluated protections enabled on ourtest branch based on PHP 8.4.0. The attacker machine usesUbuntu 22.04 and identical hardware (24-core Intel Ultra9-285HX @4.60GHz, 64GB RAM @4400MT/s). The exploitscripts are executed with Python 3.10.12.
7.2 Experiment ResultsWe rst reproduced each public exploit chain in our test en-vironment. The results in Table 3 show that the original ex-ploits of CVE-2024-2961 [11], CVE-2022-31626 [5], andCTF Case A [50] can no longer achieve arbitrary commandexecution because the new Heap Hardening protections com-pletely blocked their exploit strategy. We further manuallyanalyzed the exploit logic and conrmed that the failures werecaused by reliance on freelist corruption, rather than differ-ences in application-layer behavior. The original exploits forCVE-2019-6977 [9] and CTF Case B [33] also failed becausethey either assumed ASLR was disabled or could only tam-per with application data, which does not satisfy our goal ofcommand execution. In contrast, CVE-2023-3824 [32] andCVE-2019-11043 [26] still succeed because they rely on pow-erful but rare primitives not yet covered by current defenses:in-structure overwrite of a data pointer or a negative overowduring request parsing, respectively.ID / Case Goal Primitive Origin ReconCVE-2024-2961 RCE OOB No Yes
CVE-2023-3824 SBE OOB Yes -
CVE-2022-31626 RCE OOB No Yes
CVE-2019-11043 RCE OOB Yes -
CVE-2019-6977 SBE OOB No Yes
CTF Case A RCE OOB No Yes
CTF Case B RCE UAF No YesRCE: remote code execution. SBE: sandbox escape. OOB: out-of-boundswrite. UAF: use-after-free. Case A/B are modied from public CTF chal-lenges. "Origin" and "Recon" indicate whether public exploits and thosereconstructed using our strategy succeed in the test environment, respectively.Table 3: Existing and Rebuilt Exploits under Heap HardeningFor the ve scenarios where the original exploits failed orwere limited, we applied our exploit and defense bypass strate-gies to craft new exploits that can regain command executionability. We performed stability tests on three representativeCVEs (CVE-2024-2961, CVE-2022-31626, and CVE-2019-6977). As shown in Table 4, all tests succeeded across 100runs. The new exploits required fewer than 300 HTTP re-quests on average in the remote scenario and only two re-quests in the local sandbox-escape scenario with arbitraryscript uploads.These results show that the four implemented Heap Hard-ening protections are still not universal for all memory cor-ruptions, but they can efciently mitigate traditional freelist-based attacks. Our general bypass strategy lls this gap and re-stores reliable exploitability for multiple memory-corruptionbugs. To ensure reproducibility, we have released all exploitscripts and the complete container image so the research com-munity can build on them further.

--- page 24 ---

USENIX Association
35th USENIX Security Symposium 2813

--- page 25 ---

ID Goal Mean Worst StabilityCVE-2024-2961 RCE 245.76 507 100 %
CVE-2022-31626 RCE 284.96 507 100 %
CVE-2019-6977 SBE 2.00 2 100 %Mean and Worst indicate the number of HTTP requests sent to achieve asuccessful exploit. Stability indicates the Success Rate.
Table 4: Stability Test (100 Runs per Target)
7.3 Experiment Case StudyWe demonstrate an end-to-end attack with CVE-2024-2961.Although this vulnerability is capable of producing overowsof up to three bytes, in most real-world application cong-urations it is practically limited to a single-byte overow.Moreover, the value of the overowed byte is constrained tothe range from 0x48 to 0x4D.
7.3.1 Initial memory preparationWhile our prior discussion followed a conceptual progressionfrom primitives to full exploitation, our actual exploitationworkow begins differently. In practice, we start with theinitial memory preparation. Given that each heap zone (appli-cation heap and isolated user request heap) is aligned to 2 MB,and ASLR cannot randomize the offset within a page, partiallyoverwriting a valid pointer grants us the ability to pivot it tosomewhere else in the Zend heap space. As demonstrated in§5, we rst allocate a sequence of Buckets, then free it, thenthere will be a large amount of residualzvalas well as hashand key pointers on the heap. This is an important step, as wecannot use arbitrary data as a reference-countedzvalfor nowdue to the encoding issues discussed in §3.2. Then we allocatea string to partially overwrite the value pointer of a residualzvalto pivot it to somewhere. Since the escape character willbe inserted into the lower address of the string, we can safelyoverwrite the pointer without the encoding issue.
7.3.2 Access our fake bucket and x the access keyWith the exploitation technique in §5 and §6, we use thevulnerability to corrupt the rst index of the index lookuparray, making it point to the fake bucket built in §7.3.1.Then we spray multiple strings to re-occupy the memorypointed by the residual key pointer in the fake bucket (whichis a pointer tozend_string). The string is carefully craftedas shown in §6 to make sure that it has the same hash valueas the residual hash in the bucket. Now operations such as$table[$key]and$table[$key] = $vwill be directed toour fake bucket. We leverage our heap fengshui technique in§6 to precisely control the memory layout. Specically, wearrange allocations such that azvalwhose type tag referencesthezend_stringdestined for return, resides at an addresspointed by our overwritten residual value pointer. Then thedecrement primitive will be applied to the type tag.This grants us an address leak. All these memory allocatingand freeing operations of this and the previous step can bedone in one request as shown in §6.
7.3.3 Arbitrary code executionWe craft fake array by spraying a sequence ofzvalwith re-peated payload[0x700000001, arg0, pc]in Figure 12.Since the arraypayload["key"]is integer-indexed, theparsedzend_arraywill be set to packed mode. Whenthe array is in packed mode, the storage buffer will be asimple sequence ofzval. Threezvals take0x30bytesof memory, and theirzval.valueelds overlap with theGC header,arData, andpDestructorof azend_arrayrespectively. For the0x0000000700000001in payload,1is the reference count,0x7means this object should bedestroyed withzend_array_destroy, which will invokearray->pDestructor, i.e., thepcin payload. Note that wekeep the payload of step one in the request data, but sprayour fake array into the memory pointed by the residual valuepointer. Then, when the interpreter executes$table[$key]
= $v, the reference count of our fake array will be decreasedto 0 and invokezend_array_destroy. Since we have set upour array->pDestructor, it will then call pc(arg0).
payload = {
"key": [
0x0000000700000001, arg0, pc,
] * 0x400
}
Figure 12: Payload Used to Craft Fake Array
8 Mitigation DiscussionThis section discusses mitigation directions in two parts. Werst revisit the PHP heap hardening roadmap and analyzehow its unreleased or proposal-stage defenses would affectthe generic attack path identied in this paper. We then presenttwo targeted hardening checks that we implemented and eval-uated to block this path.
8.1 Roadmap Defense DirectionsThe PHP heap hardening roadmap can be grouped into threestages of maturity. Shadow Pointer and Unlink Abuse Pre-vention are already merged into stable releases. Both haveproven effective and forced attackers away from freelist poi-soning, which motivates the built-in-object path studied inthis paper. Read-only Metadata and Further Heap Isolationhave prototypes but are not yet merged, and Guard Pages and

--- page 26 ---

2814 35th USENIX Security Symposium
USENIX Association

--- page 27 ---

Freelist Randomization remain proposals without prototypecode. We focus on these four items below. For the prototypes,we analyze what they contribute and where they fall short.For the proposals, we discuss how they could be implementedand to what extent they would block the generic attack paththat we identied.(1) Read-only Metadata protects allocator hooks inzend_mm_heap, with a prototype that has reached a stabledesign. An earlier custom-heap variant was rejected out ofconcern [3] for the debugging value these pointers provide.The later Read-only Metadata prototype remains unmerged,with maintainers questioning [4] whether its roughly 0.6%runtime cost is justied by the protection it provides. We viewthis protection as offering limited benet under our threatmodel. Once an attacker can corrupt allocator metadata, theunderlying write primitive is already strong enough to beredirected to writable interpreter objects, as in §5.1.2, and theASLR probe in §5.2.2 can further expose writable structuresinside the PHP and libc images. Read-only Metadata there-fore raises exploitation cost without reducing reliability forattackers who reach this stage.(2) Further Heap Isolation is still under development, itplans to put objects of the same types into the same chunk,avoiding the mix of different types of objects (this is similarto AutoSlab [28] in the Linux kernel). Further Heap Isolationdirectly addresses our threat model, since it disrupts remoteheap shaping before the attacker reaches an object-corruptionpath. Our attack assumes that parser-allocated and victim ob-jects can be arranged at predictable page-level positions. If theobjects listed in Table 1 are placed in dedicated heaps that donot share pages, this assumption no longer holds and genericremote exploitation against built-in PHP objects would nolonger be feasible.(3) Guard Pages insert unmapped pages between freelistsor large allocations to prevent linear access across them andmitigate cross-page overows. Our exploit does not rely oneither primitive, so xed-size guard pages contribute little toclosing the path in this paper. A randomized variant [54,55]is more relevant, since the information leak in §5.2.1 andthe control ow hijack in §5.1.2 both depend on page-levelfengshui. Randomized guard pages would inject page-levelentropy at low engineering cost. The tradeoff is some address-space fragmentation and runtime overhead.(4) Freelist Randomization, inspired by theSLAB_FREELIST_RANDOM[16] mitigation in the Linuxkernel, has also been proposed but not yet implemented.It randomizes slot order within each freelist at low cost,since randomization is only required at freelist initialization.This breaks a core assumption of our exploit as the relativedistance between two same-size objects will be no longerpredictable, so a short overow cannot reliably reach a choseneld in a neighboring object. The primitive transformationin §4.2 also breaks, since secondary targets such as the fakeBucketin Figure 5 can no longer be placed at known offsets.LIFO reuse is generally preserved, so UAF primitives remainavailable, but their secondary targets become equally hard topredict. The remaining gap is page-level spraying: an attackerwho exhausts a freelist can still treat the page-aligned regionas a single spraying unit, and the page-level fengshui in §6.1can partially bypass intra-freelist randomization. Freelistrandomization is therefore best paired with isolation orrandomized guard pages.Overall, isolation and randomization are the directions thatmost directly affect this path, while targeted metadata protec-tion offers more limited benet.
8.2Targeted Hardening for the RemainingGeneric PathBeyond the roadmap, we implemented and evaluated twotargeted checks. Each independently breaks the generic attackpath in this paper.
Patch-hashtable: Validate that a requested hashtable indexdoes not exceednum_usedbefore the selectedBucketis used.This blocks the forgedBucketstep in §4.2, which we rely onto convert a weak one-byte overow into stronger increment
and decrement primitives.
Patch-refcnt: On every hashtable operation that updates arefcount, such as replacing or reading an entry, validate thatthe target address lies inside the PHP heap and points to acorrectly alignedzend_refcountedobject. This invalidatesthe arbitrary increment and decrement primitives and alsoblocks the ASLR probe in §5.2.2 and the destructor-basedcontrol ow hijack in §5.1.2.The two checks sit at different points in the exploit chain.Patch-hashtable targets primitive transformation and onlyneeds to harden one generic object, which keeps its cost low.It is worth adopting on its own, sincezend_arrayis theonly built-in object we surveyed that enables generic remoteprimitive transformation. Patch-refcnt sits further along thepath and covers strong primitives that do not pivot through ahashtable. The tradeoff is that it instruments a hotter code pathand carries higher cost. We view Patch-refcnt as a stopgapthat becomes less necessary if PHP adopts the isolation andrandomization defenses discussed above.We measured both checks under the environment in §7.1.Patch-hashtable mitigates three cases in Table 4 with a 0.17%overhead. CTF Case A and Case B start from stronger primi-tives that do not pivot through a hashtable, so they fall outsideits scope. Patch-refcnt mitigates four cases with an 8.86%overhead, consistent with the broader code path it covers. Asfor the last case, CTF Case A exploits the shadow pointerimplementation aw discussed in §4.1, and PHP maintainershave addressed it with two subsequent patches [46,47].

--- page 28 ---

USENIX Association
35th USENIX Security Symposium 2815

--- page 29 ---

9 Related WorkWe rst review prior attack research and point out how ourapproach differs. We then examine existing defense work andexplain how it relates to PHP's heap hardening features.Exploiting memory corruption in PHP interpreter. Gol-lum [21] aims to automatically generate exploits for mem-ory corruption bugs in PHP. It uses its custom allocator,ShapeShifter, to mimic PHP's ZendMM allocation behav-ior and locate the desired heap layout. With the help of Shrikeand a genetic algorithm, Gollum produces a set of PHP codefragments that recreate the same layout under ZendMM. Af-ter controlling the positions of the overow source and thetarget object, Gollum overwrites the target's function pointerand redirects it to a One Gadget to nish the exploit. WhileGollum can build the expected layout for relatively large over-ows when the attacker can run arbitrary PHP code, it can-not create a valid layout for a PHP remote exploit. In thesereal-world cases disclosed in the last ve years, the availableprimitives are relatively weak, and new mitigations make ear-lier heap manipulation tricks ineffective. Moreover, Gollumassumes that ASLR is disabled, and, as noted in §3.2, usingOne Gadget to exploit the PHP interpreter does not providearbitrary command execution. Consequently, the proofs ofconcept produced by Gollum still need extra adjustment, suchas combining them with the techniques in §5, before theybecome full exploits. The ideas in this work can enlarge Gol-lum's search space and help it produce exploits that work inmore restrictive, real-world scenarios. This work offers anopportunity to strengthen tools like Gollum.Charles Fol et al. proposed “Generic Remote Exploit Tech-niques for the PHP Allocator”. [10] Their method overwritesthe least-signicant bytes of a freelist's next pointer, allowingthe pointer to be hijacked to almost any nearby address. Thishijack creates overlapping slots and lets the attacker modifyarbitrary data on the heap. Before heap hardening was de-ployed, this was a powerful remote exploitation technique,but PHP's new protections can effectively detect attemptsto corrupt the freelist pointers and thus disable the attack.In addition, the technique proposed by Charles Fol et al. as-sumes the attacker can forge structures such aszend_arrayby spraying raw data directly into the web application's heap.However, heap isolation prevents raw spraying and mitigatesthis structure-forging trick. Our work introduces several newtechniques that can still achieve arbitrary heap writes. We alsouse the method in §6 to regain the ability to spray raw datainto the application heap under restricted conditions.Bypassing safety defenses. Prior work has also studiedhow limited memory-corruption primitives bypass allocatoror platform defenses. SLUBStick [31] turns cross-cache at-tacks into arbitrary read/write primitives through a slab tim-ing side channel. System Register Hijacking [35] modiesprivileged registers to bypass kernel defenses such as SMEP,SMAP, KASLR, and (Fine-)IBT [15]. On The Effectivenessof Address-Space Randomization [53] exploits the low en-tropy limitation of ASLR on 32-bit systems to bypass it withina few hundred seconds. However, on 64-bit systems, the en-tropy of ASLR has been strengthened by six orders (2
20),making this technique less effective. K-leak [27] combinesmemory errors in 64-bit Linux kernels to bypass KASLR.ARCHEAP [66] and HeapHopper [7] automatically discoverexploits that bypass allocator checks in heap allocators likeptmalloc2 [17], but their search scope is limited by memoryand time constraints.Heap Hardening. SeaK [64] and Uriah [22] isolate se-lected protectable objects into separate heaps, while random-ized slab caches [18] and SeMalloc [63] reduce the chancethat vulnerable and target objects become adjacent by select-ing among multiple heap caches. These directions are relevantto future ZendMM isolation if they can be reproduced at lowcost and prevent cross-cache attacks. Memcheck [52] and Ad-dress Sanitizer (ASAN) [51] provide broader runtime checks,but are mostly limited to testing environments due to highoverhead. Scudo [49] uses checksummed chunk headers andsize-based isolation, making it a useful reference for PHP.
10 ConclusionThis work presents the rst systematic evaluation of PHP'smemory protection mechanisms. Within this scope, we sys-tematically surveyed all built-in PHP object types and thegeneric attack paths available to remote attackers. We iden-tied implementation aws and proposed a generalized ex-ploitation strategy that transforms weak primitives, includ-ing single-byte overows, into reliable arbitrary commandexecution, bypassing all evaluated heap hardening defenses.Our techniques are effective in both remote code executionand sandbox escape scenarios. We validated our approach byreviving real-world CVEs with all evaluated protections en-abled and conrmed its reliability through automated stabilitytesting. We further discussed deployable mitigations to offerinsights into practical strategies for improving PHP's memorysafety. Our results highlight the limitations of existing mitiga-tions and motivate the development of comprehensive modelsfor securing PHP's memory.
AcknowledgmentsWe thank the anonymous reviewers and our shepherd for thecareful and thorough feedback, which substantially improvedthis paper. We are also grateful to Trent Jaeger for his earlyguidance on this project.

--- page 30 ---

2816 35th USENIX Security Symposium
USENIX Association

--- page 31 ---

Ethical ConsiderationsWe structure this discussion around stakeholder analysis andtwo phases of this work: the research process and publica-tion of results. We then discuss mitigations for the risks andexplain why conducting and publishing this study is justied.Stakeholder Analysis and Research Process ImpactThis work has ve stakeholder groups. The rst group isthe PHP development team, especially maintainers responsi-ble for heap hardening. The second group is PHP operators,hosting providers, and cloud platforms that deploy PHP inter-preters. The third group is PHP application and frameworkdevelopers, whose code paths may expose decoding and allo-cation behavior that affects exploitability. The fourth groupis the security research community, which studies interpreterexploitation, heap hardening, and memory-safety defenses.The fth group is end users and organizations that rely onPHP-based infrastructure, because exploitation and mitigationoutcomes affect their data, services, and operations.The study uses only existing PHP interpreter memory cor-ruption CVEs and introduces no new vulnerabilities. We alsofollowed responsible disclosure for the implementation awfound in the heap hardening mechanism. The PHP developerspatched the issue after our report. This protects maintain-ers, operators, and end users before publication. It also givesthe community a clearer view of which results depend on apatched implementation aw and which results remain rele-vant to PHP's interpreter behavior.
Impact of Publication: Positive impactsFor maintainers, this work evaluates current heap hardeningunder a realistic remote attacker model, shows which tradi-tional paths are blocked, and identies where determinedattackers can still adapt. For operators and hosting providers,it reduces false condence and supports complementary de-fenses such as sandboxing, monitoring, WAFs, rate limiting,and anomaly detection. For application and framework de-velopers, it explains why exposed JSON and XML decodingpaths matter after an interpreter memory corruption bug. Forthe research community, the artifacts provide Docker les,reference commands, and standalone implementations as areproducible baseline. For end users and organizations, thepaper claries that heap hardening narrows exploitation butdoes not eliminate it, helping them assess the security postureof service providers and advocate stronger layered defenses.
Impact of Publication: Negative impactThe main risk is misuse. The paper describes exploit strategiesthat can help attackers adapt after PHP heap hardening isdeployed. These strategies may lower the engineering effortneeded to turn a future PHP memory corruption vulnerabilityinto command execution. The study does not introduce anew PHP memory corruption vulnerability or applicationentry point. The remaining risk comes from lowering theeffort needed to adapt future exploits after such vulnerabilitiesalready exist. Open-source artifacts may also increase thisrisk if they are used outside local test environments.
MitigationsWe use several mitigations to reduce harm. First, we dis-closed the implementation aw to PHP maintainers beforepublication and separate that patched aw from the remainingtechniques. Second, we pair the attack analysis with defensediscussion: we explain which existing mitigations are effec-tive, which paths remain open, and why additional hardeningof built-in PHP objects can raise exploitation cost. Our artifactalso includes two prototype checks that independently breakthe attack path identied in this paper, giving maintainers con-crete short-term hardening options. Third, deployment-levelmitigations. PHP's own mitigations should be complementedby sandbox restrictions, monitoring, WAFs, rate limits, andanomaly detection. Finally, future PHP hardening should eval-uate built-in PHP objects and decoding-based allocation paths,because current hardening mainly focuses on heap metadatawhile our results show that built-in objects may also needprotection.Justication for Conducting and Publishing the ResearchMove before attackers. Withholding the results would leavemaintainers and operators with less information about thelimits of current hardening. Similar strategies could still bediscovered independently, and defenders would have fewerconcrete examples for improving PHP. Publication after re-sponsible disclosure gives the community a safer path: theimplementation aw is patched, the assumptions are explicit,and the paper provides mitigation directions and targetedpatch implementations.Proactively addressing the misuse risk. We address therisk through responsible disclosure and concrete defense rec-ommendations. In particular, our proposed mitigations, al-ready implemented in the artifacts, give PHP maintainersconcrete options for stopping the generic exploit strategy dis-cussed in the paper.Longer-term impact. Overall, we believe publishing thispaper will bring more awareness of PHP's security posture tothe security community, which will inform future hardeningdirections. Even though there is some risk of misuse in theshort term, it will lead to a more secure PHP interpreter inthe long run. In other words, the long-term benets to PHPmaintainers, application developers, operators, end users, andthe research community outweigh the short-term risk.

--- page 32 ---

USENIX Association
35th USENIX Security Symposium 2817

--- page 33 ---

Open ScienceOur artifacts have been released at the following link:http
s://zenodo.org/records/20401797. All experimentalenvironments include Docker les and reference commandsthat facilitate easy and stable reproduction. We also providestandalone implementations for all pseudocode that appear inthe paper.
References
[1]Adobe. Magento open source.https://www.magent
o.com, 2025.
[2]Arnaud Le Blanc. The php interpreter.https://gi
thub.com/arnaud-lb/php-src/tree/mm-zones,2024.
[3]bwoebi. PHP pr 14570: Make some parts of_zend_mm_heap read-only at runtime (the rst com-ment).https://github.com/php/php-src/pull/
14570#issuecomment-2168457515, 2024.
[4]bwoebi. PHP pr 14570: Make some parts of_zend_mm_heap read-only at runtime (the second com-ment).https://github.com/php/php-src/pull/
14570#issuecomment-2248354450, 2024.
[5]CFandR-github. CVE-2022-31626 analysis.https:
//github.com/CFandR-github/PHP-binary-bugs/
blob/main/cve_2022_31626, 2022.
[6]SSD Secure Disclosure. PHP spldoublylinkedlist uafsandbox escape.https://bugs.php.net/bug.php
?id=80111, 2020.
[7]Moritz Eckert, Antonio Bianchi, Ruoyu Wang, YanShoshitaishvili, Christopher Kruegel, and Giovanni Vi-gna. HeapHopper: Bringing bounded model checking toheap implementation security. In 27th USENIX SecuritySymposium (USENIX Security 18), pages 99–116, Balti-more, MD, August 2018. USENIX Association. URL:https://www.usenix.org/conference/usenixse
curity18/presentation/eckert.
[8]César Estébanez, Yago Saez, Gustavo Recio, and Pe-dro Isasi. Performance of the most common non-cryptographic hash functions. Software: Practice andExperience, 44(6):681–698, 2014. URL:https://
onlinelibrary.wiley.com/doi/abs/10.100
2/spe.2179,arXiv:https://onlinelibrary.
wiley.com/doi/pdf/10.1002/spe.2179,doi:
10.1002/spe.2179.
[9]Charles Fol. imagecolormatch() oob heap write exploit.https://github.com/cfreal/exploits/tree/ma
ster/CVE-2019-6977-imagecolormatch, 2019.
[10]Charles Fol. Generic remote exploit techniques for thephp allocator, and 0days.https://www.blackalps.
ch/ba-22/talks.php, 2022.
[11]Charles Fol. Iconv, set the charset to rce: Exploiting theglibc to hack the php engine (part 1).https://blog.l
exfo.fr/iconv-cve-2024-2961-p1.html, 2024.
[12]Charles Fol. Iconv, set the charset to rce: Exploiting theglibc to hack the php engine (part 2).https://blog.l
exfo.fr/iconv-cve-2024-2961-p2.html, 2024.
[13]Cake Software Foundation. Cakephp: The rapid devel-opment framework for php - ofcial repository.https:
//cakephp.org, 2025.
[14]CodeIgniter Foundation. Open source php framework(originally from ellislab).https://github.com/bci
t-ci/CodeIgniter, 2025.
[15]Alexander J. Gaidis, Joao Moreira, Ke Sun, AlyssaMilburn, Vaggelis Atlidakis, and Vasileios P. Kemerlis.Fineibt: Fine-grain control-ow enforcement with indi-rect branch tracking. In Proceedings of the 26th Interna-tional Symposium on Research in Attacks, Intrusionsand Defenses, RAID '23, page 527–546, New York,NY, USA, 2023. Association for Computing Machinery.doi:10.1145/3607199.3607219.
[16]Thomas Garnier. mm: Slab freelist randomization.ht
tps://lore.kernel.org/lkml/1460138602-853
86-1-git-send-email-thgarnie@google.com/T/,2016.
[17]W GLOGER. Ptmalloc.http://www.malloc.de,2006.
[18]Ruiqi GONG. Randomized slab caches for kmalloc().https://lkml.org/lkml/2023/5/8/206, 2023.
[19]PHP Documentation Group. Description of core php.inidirectives.https://www.php.net/manual/en/ini.
core.php, 2025.
[20]PHP Documentation Group. Fastcgi process manager(fpm).https://www.php.net/manual/en/install.
fpm.php, 2025.
[21]Sean Heelan, Tom Melham, and Daniel Kroening. Gol-lum: Modular and greybox exploit generation for heapoverows in interpreters. In Proceedings of the 2019ACM SIGSAC conference on computer and communica-tions security, pages 1689–1706, 2019.
[22]Kaiming Huang, Mathias Payer, Zhiyun Qian, JackSampson, Gang Tan, and Trent Jaeger. Top of the heap:Efcient memory error protection of safe heap objects.In Proceedings of the 2024 on ACM SIGSAC Confer-ence on Computer and Communications Security, pages1330–1344, 2024.

--- page 34 ---

2818 35th USENIX Security Symposium
USENIX Association

--- page 35 ---

[23]Eyal Itkin. Safe-linking – eliminating a 20 year-oldmalloc() exploit primitive.https://research.check
point.com/2020/safe-linking-eliminating-a
-20-year-old-malloc-exploit-primitive, 2020.
[24]Eddie Kohler. Hotcrp conference review software.ht
tps://read.seas.harvard.edu/~kohler/hotcrp,2025.
[25]Laravel. The laravel framework.https://laravel.
com, 2025.
[26]Emil Lerner. Phuip-fpizdam.https://github.com/n
eex/phuip-fpizdam, 2019.
[27]Zhengchuan Liang, Xiaochen Zou, Chengyu Song, andZhiyun Qian. K-leak: Towards automating the gener-ation of multi-step infoleak exploits against the linuxkernel. In NDSS. Internet Society, 2024.
[28]Zhenpeng Lin. How autoslab changes the memory un-safety game.https://grsecurity.net/how_autos
lab_changes_the_memory_unsafety_game, 2021.
[29]LoadForge. Enhance security by disabling dangerousphp functions.https://loadforge.com/guides/d
isable-dangerous-php-functions-for-enhance
d-security, 2025.
[30]ARM LTD. ARMv8 architecture reference manual, forarmv8-a architecture prole (arm ddi 0487).https:
//developer.arm.com/documentation/ddi0487/,2024.
[31]Lukas Maar, Stefan Gast, Martin Unterguggenberger,Mathias Oberhuber, and Stefan Mangard. SLUB-Stick: Arbitrary memory writes through practical soft-ware Cross-Cache attacks within the linux kernel. In33rd USENIX Security Symposium (USENIX Security24), pages 4051–4068, Philadelphia, PA, August 2024.USENIX Association. URL:https://www.usenix.o
rg/conference/usenixsecurity24/presentatio
n/maar-slubstick.
[32]maplgebra. CVE-2023-3824: Lucky off-by-one (two?).https://m4p1e.com/2024/03/01/CVE-2023-3824,2024.
[33]maplgebra. N1ctf24 php master writeup.https://m4
p1e.com/2024/11/12/n1ctf24-php-master, 2024.
[34]Trilby Media. Grav - a modern at-le cms.https:
//getgrav.org/, 2025.
[35]Jennifer Miller, Manas Ghandat, Kyle Zeng, HongkaiChen, Abdelouahab Habs Benchikh, Tiffany Bao, RuoyuWang, Adam Doupé, and Yan Shoshitaishvili. Systemregister hijacking: Compromising kernel integrity byturning system registers against the system. In 34thUSENIX Security Symposium (USENIX Security 25),pages 7427–7446, 2025.
[36]MITRE. CVE-2019-11043.https://cve.mitre.or
g/cgi-bin/cvename.cgi?name=CVE-2019-11043,2019.
[37]MITRE. CVE-2019-6977.https://cve.mitre.or
g/cgi-bin/cvename.cgi?name=CVE-2019-6977,2019.
[38]MITRE. CVE-2022-31626.https://cve.mitre.or
g/cgi-bin/cvename.cgi?name=CVE-2022-31626,2022.
[39]MITRE. CVE-2024-2961.https://cve.mitre.or
g/cgi-bin/cvename.cgi?name=CVE-2024-2961,2024.
[40]Julien Pauli, Nikita Popov, and Anthony Ferrara. PHPinternals book.https://www.phpinternalsbook.c
om/index.html.
[41]Julien Pauli, Nikita Popov, and Anthony Ferrara. Zendmemory manager.https://www.phpinternalsbook
.com/php7/memory_management/zend_memory_ma
nager.html, 2024.
[42]PHP Group. PHP pr 13943: Add two checks forzend_mm_heap's integrity.https://github.com
/php/php-src/pull/13943, 2024.
[43]PHP Group. PHP pr 14054: Detect heap freelist corrup-tion.https://github.com/php/php-src/pull/14
054, 2024.
[44]PHP Group. PHP pr 14304: Remote heap feng shui /heap spraying protection.https://github.com/php
/php-src/pull/14304, 2024.
[45]PHP Group. PHP pr 14339: Add an unlink check forphp_stream_bucket_unlink.https://github.com/p
hp/php-src/pull/14339, 2024.
[46]PHP Group. PHP pr 16765: Refresh zend mm shadowkey on fork.https://github.com/php/php-src/p
ull/16765, 2024.
[47]PHP Group. PHP pr 19287: Call php_child_init() afterfork during preloading.https://github.com/php/p
hp-src/pull/19287, 2025.
[48]phpMyAdmin. A web interface for mysql and mariadb.https://www.phpmyadmin.net, 2025.
[49]LLVM Project. Scudo hardened allocator.https://ll
vm.org/docs/ScudoHardenedAllocator.html.

--- page 36 ---

USENIX Association
35th USENIX Security Symposium 2819

--- page 37 ---

[50]r3kapig. Securinets ctf quals 2024(jeopardy).https:
//r3kapig-not1on.notion.site/Securinets-C
TF-Quals-2024-Jeopardy-118ec1515fb980eeade
bc7b6df22a7a1, 2024.
[51]Konstantin Serebryany, Derek Bruening, AlexanderPotapenko, and Dmitriy Vyukov.fAddressSanitizerg:A fast address sanity checker. In 2012 USENIX annualtechnical conference (USENIX ATC 12), pages 309–318,2012.
[52]Julian Seward and Nicholas Nethercote. Using valgrindto detect undened value errors with bit-precision. InUSENIX Annual Technical Conference, General Track,pages 17–30, 2005.
[53]Hovav Shacham, Matthew Page, Ben Pfaff, Eu-Jin Goh,Nagendra Modadugu, and Dan Boneh. On the effective-ness of address-space randomization. In Proceedings ofthe 11th ACM conference on Computer and communi-cations security, pages 298–307, 2004.
[54]Sam Silvestro, Hongyu Liu, Corey Crosser, ZhiqiangLin, and Tongping Liu. Freeguard: A faster secure heapallocator. In Proceedings of the 2017 ACM SIGSACConference on Computer and Communications Security,CCS '17, page 2389–2403, New York, NY, USA, 2017.Association for Computing Machinery.doi:10.1145/
3133956.3133957.
[55]Sam Silvestro, Hongyu Liu, Tianyi Liu, Zhiqiang Lin,and Tongping Liu. Guarder: A tunable secure allocator.In 27th USENIX Security Symposium (USENIX Secu-rity 18), pages 117–133, Baltimore, MD, August 2018.USENIX Association. URL:https://www.usenix.o
rg/conference/usenixsecurity18/presentatio
n/silvestro.
[56]Yii Software. Yii 2: The fast, secure and professionalphp framework.https://www.yiiframework.com,2025.
[57]Symfony Core Team. The symfony php framework.https://symfony.com, 2025.
[58]Chris Valasek. Understanding the low fragmentationheap. Black Hat USA, 11, 2010.
[59] Julien Voisin. Heap hardening. https://github.com
/php/php-src/issues/14083, 2024.
[60]Julien Voisin. Make some parts of _zend_mm_heapread-only at runtime.https://github.com/php/php
-src/pull/14570, 2024.
[61]Jakub Vrana. Database management in a single php le.https://www.adminer.org, 2025.
[62]W3Techs. Usage statistics of php for websites.https:
//w3techs.com/technologies/details/pl-php,2026.
[63]Ruizhe Wang, Meng Xu, and N Asokan. Semalloc:Semantics-informed memory allocator. In Proceedingsof the 2024 on ACM SIGSAC Conference on Computerand Communications Security, pages 1375–1389, 2024.[64]Zicheng Wang, Yicheng Guang, Yueqi Chen, ZhenpengLin, Michael Le, Dang K Le, Dan Williams, Xinyu Xing,Zhongshu Gu, and Hani Jamjoom.fSeaKg: Rethinkingthe design of a secure allocator forfOSgkernel. In33rd USENIX Security Symposium (USENIX Security24), pages 1171–1188, 2024.
[65]WordPress. Blog tool, publishing platform, and cms.https://wordpress.org, 2025.
[66]Insu Yun, Dhaval Kapil, and Taesoo Kim. Automatictechniques to systematically discover new heap exploita-tion primitives. In 29th USENIX Security Symposium(USENIX Security 20), pages 1111–1128. USENIX As-sociation, August 2020. URL:https://www.usenix
.org/conference/usenixsecurity20/presentat
ion/yun.

--- page 38 ---

2820 35th USENIX Security Symposium
USENIX Association

--- page 39 ---

Appendix
A Timeline of PHP Heap HardeningThe PHP heap hardening roadmap was opened on Apr. 30,2024 and lists allocator unlink checks, freelist shadow point-ers, read-only metadata, guard pages, freelist randomization,heap isolation, and related isolation ideas [59]. The protec-tions in Table A1 are the ones that have available prototypesand materially affect our evaluation.Protection StatusShadow pointer [43] Merged to PHP 8.4.0+
Fork-refresh Patches [46,47] Merged to PHP 8.5.0+
Unlink Abuse Prevention [42] Merged to PHP 8.4.0+
Read-only metadata [60] Closed prototype
Remote heap isolation [44] Open prototypeTable A1: Available PHP heap hardening protections.The freelist shadow pointer PR was merged into master onJun. 12, 2024 [43], and the unlink checks were merged intomaster on Apr. 23, 2024 [42], while the stream-bucket vari-ant [45] remains open. Two fork-refresh patches were latermerged into master on Jul. 29, 2025 [46,47] to x the shadowpointer randomization issue. Heap isolation is not released,but it directly targets remote heap shaping, so evaluating ithelps estimate the value of this direction. Read-only Metadatahas two versions as discussed in §2.4 but neither is deployedor considered an imminent mitigation. We include the laterversion which is more practical according to the discussionthread [60] only as a representative metadata-protection de-sign. §5 addresses this class of design, while the techniques in§4 and §6 remain relevant regardless of whether PHP adoptsread-only metadata.Algorithm 1 Reverse DJBX33A Hash1: Input: Target hash value H, target input length n
2:Output: Stringsof lengthnsuch thatDJBX33A(s) = H
3: H
0
 DJBX33A(n zero bytes)
4: D (H H
0
) mod 2
64
5: seq []
6: while D  33 do
7: seq.append(D mod 33)
8: D 

D33

9: end while
10: seq.append(D)
11: s n - len(seq) zero bytes k reverse(seq)
12: return sName Stars JSON XML M YTop 5 PHP Frameworks on GitHubLaravel [25] 34479 X X X 
Symfony [57] 30922 X X X X
CodeIgniter [14] 18226  X X 
Yii 2 [56] 14319 X X X 
CakePHP [13] 8785 X X X Popular PHP ApplicationsWordPress [65] 20071 X X X 
Grav [34] 14903 X X X X
Magento2 [1] 11768 X X X 
phpMyAdmin [48] 7495 X X X X
HotCRP [24] 389 X X X M refers to the serialized format from theserializefunction in PHP and Yrefers to the YAML serialization language.Table A2: Comparison of supported serialization formats us-age in popular open source PHP frameworks and applications.Figure 13: Spray String with Controllable Hash Value andPartially Controllable Content
Figure 14: Convert heap overow to out-of-bounds read

--- page 40 ---

USENIX Association
35th USENIX Security Symposium 2821

--- page 41 ---

!"#$$$$%&'()$!!"#$%&'()*+,-./012222222234567801&9:;))%&'#;;''%'!%8<)'!=*>3?@ABC=*>*DE=FG

--- page 42 ---

!"#$%&"'(")"(*(&+,&&&-"#$%."'("/"(*(&+0&&&-"#$%1"'("2"(*(&+3&&&-"#$%."'(4566789:()66;<9=$(>965$(;?(#$%&8@:()66;<9=$(>965$(;?(#$%.8<:()66;<9=$(>965$(;?(#$%18A:()66;<9=$(4$B(>965$(;?(#$%.(94A(?C$$(=D$(;6A(>965$(;?(#$%.)66;<9=$A(?;C(#$%&)66;<9=$A(?;C(#$%.)66;<9=$A(?;C(#$%1EC$$(F$F;C%

--- page 43 ---

!"#$%&"'(")"(*(&+,&&&-"#$%."'("/"(*(&+0&&&-"#$%12'(3456$374554%-"#$%."'(89::;<=(>$4?$5@45A434@?$B359C3D5)::DC43$(EFC3FG(H9II$5J8?$+(:DD#9K(4554%

--- page 44 ---

!"#$%&'%($&)$*%+,-$................................///........$%&0#'&-&$%&0#'&-&$%&0#'&-&1&*2%-30%#4+56!"#$%&'%($&)$*%+,-$................................///........$%&0#'&-&$%&0#'&-&$%&0#'&-&1&*2%-30%#4+567&8#"6((20-#-$%#1&*2%#064+-%(798#"6((20-#-$%#*%+,-$#65#)-(4+,:+-%(0(%-#$%&0#'&-&#&)#)-(4+,;2-#65#962+'#(%&'"6((20-#-&(,%-;1%(5*6<#'&-&=1&*=1&*=%+'>)-(4+,=%+'>)-(4+,?6<%(@4,$%(

--- page 45 ---

middlewareuserattackerPHP Interpreterstatic resourcesWeb Server environmentHTTP(s) requestCGI call InterpretedApplication’s 
PHP scriptsmiddleware configure 
errors / memory errorsinterpreter
memory errorsweb application
logic errorsconfigs and
saved cache

--- page 46 ---

rw- zend_heap[0x00007ffff4600000 - 0x00007ffff4800000)r-- /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
[0x00007ffff482a000 - 0x00007ffff4831000)rw-
[0x00007ffff4888000 - 0x00007ffff4891000)r-- /usr/lib/x86_64-linux-gnu/libffi.so.8.1.0
[0x00007ffff4891000 - 0x00007ffff4893000)r-x /usr/lib/x86_64-linux-gnu/libffi.so.8.1.0[0x00007ffff4893000 - 0x00007ffff489a000)…
…r-- /usr/lib/x86_64-linux-gnu/libc.so.6
[0x00007ffff780d000 - 0x00007ffff7835000)…
…
…
…rw- FPM_heap[0x000059adf7410000 - 0x000059adf76c0000)…
…r-x /usr/sbin/php-fpm[0x000059adca400000 - 0x000059adca908000)…
…

--- page 47 ---

':Ly%#%'2#2'E#E'¥'
