CVE-2022-31629

Improper Input Validation (4.16)
Affects
PHP
in
PHP
No items found.
Versions
<7.4.32, >=8.0.0 <8.0.24, >=8.1.0 <8.1.11

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 Security Bypass vulnerability (CVE-2022-31629) has been identified in the way PHP turns request variable names into keys of $_COOKIE, which allows a network attacker or an attacker who controls a sibling subdomain to set an ordinary cookie that a PHP application receives under a __Host- or __Secure- name, and so to defeat protections that rely on those cookie prefixes. PHP tracks this issue as bug #81727.

Per MITRE CWE-20: The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.

This issue affects all versions of PHP before 7.4.32, PHP 8.0 before 8.0.24 and PHP 8.1 before 8.1.11, which includes every End-of-Life release line from PHP 5.6 through 7.3, each up to its final release.

Details

Module Info

Vulnerability Info

This Medium-severity vulnerability is found in the request variable handling of all PHP versions before 7.4.32, 8.0 before 8.0.24 and 8.1 before 8.1.11, including every End-of-Life release line from PHP 5.6 through 7.3, which never received the upstream fix. The CVE record from the PHP project has no CVSS score of its own; CISA-ADP scores it 6.5 under CVSS 3.1 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N), and this entry uses that score.

Browsers give cookies whose names start with __Host- or __Secure- special protection: such a cookie can only be set by a secure (HTTPS) origin, and a __Host- cookie cannot be set by another subdomain. Applications use these prefixes to trust a cookie's integrity, for example for CSRF tokens. For compatibility with the old register_globals behavior, PHP rewrites spaces and dots in the names of GET, POST and cookie variables to underscores before storing them. The mangling in php_register_variable_ex() reads:

/* ensure that we don't have spaces or dots in the variable name (not binary safe) */
for (p = var; *p; p++) {
    if (*p == ' ' || *p == '.') {
        *p='_';
    } else if (*p == '[') {
        is_array = 1;
        ip = p;
        *p = 0;
        break;
    }
}

A cookie named ..Host-name has no prefix as far as the browser is concerned, so a plain HTTP page or a sibling subdomain may set it. PHP, however, stores it in $_COOKIE as __Host-name. Because PHP keeps the first cookie it sees with a given name, an attacker-set cookie that the browser sends first can also take the place of the real __Host- cookie. The reporter showed how this defeats a double-submit CSRF protection that compares a __Host- cookie with a form field, letting a same-site attacker forge requests.

The issue affects any SAPI that registers request variables, such as php-fpm, CGI, the Apache module and the CLI built-in server, for applications that rely on __Host- or __Secure- cookies. The attacker needs to set a cookie in the victim's browser, either from a sibling subdomain or by tampering with plain HTTP traffic, and the victim then has to visit the application. Applications that do not trust cookie prefixes are not affected.

The fix drops a variable whose name only starts with __Host- or __Secure- because of mangling, with one such check for each prefix:

/* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host- */
if (strncmp(var, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(var_name, "__Host-", sizeof("__Host-")-1) != 0) {
    zval_ptr_dtor_nogc(val);
    free_alloca(var_orig, use_heap);
    return;
}

PHP later found that this fix did not cover every way of producing a prefixed name and tracked the remainder as CVE-2024-2756.

Mitigation

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

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

  • Upgrade to PHP 7.4.32, 8.0.24, 8.1.11, 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-2022-31629
PROJECT Affected
PHP
Versions Affected
<7.4.32, >=8.0.0 <8.0.24, >=8.1.0 <8.1.11
NES Versions Affected
Published date
September 28, 2022
≈ Fix date
September 29, 2022
Fixed in
Category
Improper Input Validation (4.16)
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.