CVE-2025-14178

Heap-based Buffer Overflow
Affects
PHP
in
PHP
No items found.
Versions
>=7.2.0 <8.1.34, >=8.2.0 <8.2.30, >=8.3.0 <8.3.29, >=8.4.0 <8.4.16, >=8.5.0 <8.5.1

Patch Available.

Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

PHP is a general-purpose scripting language used mostly for web development. It runs behind web servers through server APIs such as Apache mod_php and PHP-FPM, and powers content management systems and frameworks such as WordPress, Drupal, Moodle and Laravel.

A Buffer Overflow vulnerability (CVE-2025-14178) has been identified in the array_merge() function of PHP's standard library, which allows an attacker who can control the number or size of the arrays an application merges to overflow the element count PHP uses to size the result, so that the merge writes past the end of a heap buffer, which can corrupt memory or crash the process. PHP tracks this issue as GHSA-h96m-rvf9-jgm2.

Per MITRE CWE-787: The product writes data past the end, or before the beginning, of the intended buffer.

This issue affects PHP 7.2 through 8.1.33, PHP 8.2 before 8.2.30, PHP 8.3 before 8.3.29, PHP 8.4 before 8.4.16 and PHP 8.5 before 8.5.1, which includes the End-of-Life PHP 7.2, 7.3, 7.4 and 8.0 release lines through their final releases (7.2.34, 7.3.33, 7.4.33 and 8.0.30).

Details

Module Info

Vulnerability Info

This Medium-severity vulnerability is found in PHP 7.2 through 8.1.33, 8.2 before 8.2.30, 8.3 before 8.3.29, 8.4 before 8.4.16 and 8.5 before 8.5.1, including the End-of-Life PHP 7.2, 7.3, 7.4 and 8.0 release lines, which never received the upstream fix. The PHP project scores it 6.5 under CVSS 3.1 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:H). The advisory states that the bug has existed since PHP 7.1; the summed element count that overflows first appears in PHP 7.2.0, while PHP 7.1 sizes the result from the first array only.

To merge arrays efficiently, array_merge() (and array_merge_recursive(), which shares the same code) first adds up the number of elements in all of its arguments and allocates the result array with that size before copying anything. In PHP 7.4.33, the total is kept in count, a 32-bit uint32_t:

for (i = 0; i < argc; i++) {
    zval *arg = args + i;

    if (Z_TYPE_P(arg) != IS_ARRAY) {
        php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(arg));
        RETURN_NULL();
    }
    count += zend_hash_num_elements(Z_ARRVAL_P(arg));
} 

When the arguments together hold 2^32 elements or more, the sum wraps to a small number. array_init_size(return_value, count) then allocates a result that is far too small, and for packed (list-style) arrays the fast copy path fills it without further bounds checks, writing past the end of the heap buffer. HeroDevs' analysis notes that many references to the same array suffice, for example 4096 references to one array of a million elements. Even without wraparound, a total above the hash table's maximum size makes the allocation fail and stops the request. The advisory describes the result as heap corruption, with a denial of service as the lesser outcome.

Exploitation needs code that merges an attacker-controlled number of large arrays, under any SAPI. The advisory gives passing decoded JSON input to array_merge(...$array) as a possible real-world path, while describing its own proof of concept as an artificial trigger. Applications that never spread user-controlled input into array_merge(), or that limit the number and size of merged arrays, are not exposed.

The fix declares count as a 64-bit uint64_t so the sum cannot wrap, and throws an Error when the total reaches the maximum hash table size, before anything is allocated:

if (UNEXPECTED(count >= HT_MAX_SIZE)) {
    zend_throw_error(NULL, "The total number of elements must be lower than %u", HT_MAX_SIZE);
    RETURN_THROWS();
} 

HeroDevs' analysis found that the maximum hash table size on PHP 7.2 and 7.4 is twice that of PHP 8.1, so the NES releases for those lines use half of it as the limit.

Mitigation

The PHP project publishes security fixes only for its supported release lines. PHP 7.2, 7.3, 7.4 and 8.0 are End-of-Life and will not receive any public updates to address this issue.

Until an upgrade is possible, limit the number of long arrays passed to array_merge(), as the advisory recommends, for example by validating the size of decoded input before spreading it into the call.

Users of the affected components should apply one of the following mitigations:

  • Upgrade to PHP 8.1.34, 8.2.30, 8.3.29, 8.4.16, 8.5.1, or later.
  • Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.

Credits

Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Medium
ID
CVE-2025-14178
PROJECT Affected
PHP
Versions Affected
>=7.2.0 <8.1.34, >=8.2.0 <8.2.30, >=8.3.0 <8.3.29, >=8.4.0 <8.4.16, >=8.5.0 <8.5.1
NES Versions Affected
Published date
December 27, 2025
≈ Fix date
December 18, 2025
Fixed in
Category
Heap-based Buffer Overflow
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
PHP
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.