A critical vulnerability in PHP’s extract() function has been uncovered, enabling attackers to execute arbitrary code by exploiting memory corruption flaws.
The issue affects PHP versions 5.x, 7.x, and 8.x, allowing malicious actors to trigger double-free (PHP 5.x) or use-after-free (PHP 7.x/8.x) conditions, ultimately leading to remote code execution (RCE).
Technical Breakdown
According to the SSD report, the flaw stems from improper handling of the EXTR_REFS flag in extract(), which imports variables into the symbol table as references.
When overwriting existing variables, the function calls zval_ptr_dtor to destroy the original value. If the original variable is an object, its __destruct method is invoked mid-destruction, enabling attackers to manipulate the heap via crafted input:
// Example triggering the vulnerability
$malicious_array = ['var' => new ExploitableClass()];
extract($malicious_array, EXTR_REFS);
During this process, PHP’s internal zval_ptr_dtor function frees memory multiple times if an object’s destructor unsets the same variable, corrupting the heap.
In PHP 5.x, this causes a double-free, while newer versions suffer from use-after-free due to changes in memory management.
Field | Details |
Vulnerability | Critical flaw in PHP’s extract() function allows arbitrary code execution |
Affected Versions | PHP 5.x (double-free), PHP 7.x & 8.x (use-after-free) |
Root Cause | Improper memory management when using extract() with EXTR_REFS flag, especially during object destruction |
Trigger Condition | An object’s __destruct method unsets a variable during an ongoing zval_ptr_dtor call in extract() |
Vulnerability Type | Double-free (PHP 5.x), Use-after-free (PHP 7.x, 8.x) |
Impact | Heap corruption, arbitrary read/write, and remote/native code execution |
Exploitation Impact
Attackers can leverage this to:
- Overwrite critical memory structures (e.g., PHP’s HashTable or zval objects).
- Execute arbitrary native code by manipulating heap allocations to gain read/write primitives.
- Bypass security mechanisms like disable_functions by hijacking PHP’s internal function handlers.
Proof-of-concept exploits demonstrate how to chain these primitives to achieve RCE. For instance, overwriting the handler of a disabled function like system() with a legitimate address restores its execution capability1.
The PHP team has patched the issue in GitHub Advisory GHSA-4pwq-3fv3-gm94. Administrators should:
- Update PHP to the latest version immediately.
- Audit code for unsafe extract() usage, especially with user-controlled data (e.g., extract($_POST)).
- Replace extract() with explicit variable assignments or use flags like EXTR_PREFIX_ALL to isolate variables.
This vulnerability underscores long-standing risks in PHP’s extract(), which has been flagged for decades as prone to misuse. Past incidents include backdoors like:
@extract($_REQUEST);
@die($ctime($atime)); // Allows $_REQUEST['ctime']('command') execution [4]
Developers are urged to avoid extracting () entirely for user input and adopt secure coding practices.
The extract() vulnerability highlights the dangers of legacy functions in modern ecosystems.
While patches are available, proactive code reviews and dependency updates remain critical to mitigating such risks.
Organizations using PHP should prioritize upgrading and eliminating unsafe patterns to prevent exploitation.
Find this News Interesting! Follow us on Google News, LinkedIn, & X to Get Instant Updates!