CVE-2021-21703

Out-of-bounds Write
Affects
PHP
in
PHP
No items found.
Versions
<7.3.32, >=7.4.0 <7.4.25, >=8.0.0 <8.0.12

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. PHP-FPM (FastCGI Process Manager) runs PHP for web servers as a master process that manages a pool of worker processes.

A Memory Corruption vulnerability (CVE-2021-21703) has been identified in the scoreboard that PHP-FPM keeps in memory shared between its master process and its workers, which allows a local attacker who can run code inside a worker to make a master process running as root read and write memory out of bounds, and so escalate from the worker's unprivileged user to root. PHP tracks this issue as bug #81026.

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

This issue affects all versions of PHP before 7.3.32, PHP 7.4 before 7.4.25 and PHP 8.0 before 8.0.12, which includes every End-of-Life release line from PHP 5.6 through 7.2, each up to its final release.

Details

Module Info

Vulnerability Info

This High-severity vulnerability is found in the FPM SAPI of all PHP versions before 7.3.32, 7.4 before 7.4.25 and 8.0 before 8.0.12, including every End-of-Life release line from PHP 5.6 through 7.2, which never received the upstream fix. The PHP project scores it 7.8 under CVSS 3.1 (CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H).

In a typical PHP-FPM service, the master process runs as root and starts workers that switch to a less privileged user, such as www-data, before they run PHP scripts. Each pool has a scoreboard in shared memory that the master and every worker can write. It holds the pool's counters, the number of worker slots, and an array of pointers to the per-worker records, which are stored in the same shared mapping. In PHP 7.2.34, the master and the workers find a worker's record by following that pointer:

if (child_index < 0 || (unsigned int)child_index >= scoreboard->nprocs) {
    return NULL;
}

return scoreboard->procs[child_index];

Both the bound nprocs and the procs pointers live in memory that every worker can change. The reporter, Charles Fol, showed that a worker running attacker-controlled code can rewrite them so that the root master process, when it later reads or resets a worker's record, reads and writes at addresses the attacker chose, and that this can be turned into code execution as root. HeroDevs' analysis confirms the same design in the PHP 5.6 and 7.2 lines.

Exploitation needs php-fpm with a master process running as root, which is the usual service setup, and an attacker who can already run code in a worker, for example through a vulnerable PHP script or file upload. The result is local privilege escalation from the pool's user to root. Other SAPIs, such as the Apache module, CGI and the CLI, do not use this scoreboard and are not affected, and neither is an FPM setup whose master does not run as root.

The fix stores the worker records inline in the scoreboard instead of behind pointers, and the master checks indexes against the pool's configured pm.max_children, which it holds in its own memory, rather than against the shared nprocs value:

if (child_index < 0 || (unsigned int)child_index >= nprocs) {
    return NULL;
}

return &scoreboard->procs[child_index];

Mitigation

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

Until an upgrade is possible, where the setup allows it, run the php-fpm master process as the same unprivileged user as its workers instead of as root, so that a compromised worker has no more privileged process to attack.

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

  • Upgrade to PHP 7.3.32, 7.4.25, 8.0.12, 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
High
ID
CVE-2021-21703
PROJECT Affected
PHP
Versions Affected
<7.3.32, >=7.4.0 <7.4.25, >=8.0.0 <8.0.12
NES Versions Affected
Published date
October 25, 2021
≈ Fix date
October 21, 2021
Fixed in
Category
Out-of-bounds Write
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.