CVE-2022-37454

Integer Overflow or Wraparound
Affects
PHP
in
PHP
No items found.
Versions
>=7.2.0 <7.4.33, >=8.0.0 <8.0.25, >=8.1.0 <8.1.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. Its hash extension, which is always built, provides hash(), hash_init() and hash_update(), and implements the SHA-3 algorithms with a bundled copy of the Keccak team's XKCP reference code.

A Buffer Overflow vulnerability (CVE-2022-37454) has been identified in the Keccak sponge code that PHP's hash extension bundles for SHA-3, in which an integer overflow can lead to a buffer overflow when very large inputs, close to 4 GiB, are hashed incrementally. Upstream, an attacker who can make an application hash such data may be able to crash PHP or, according to the CVE record, execute arbitrary code or break the hash's cryptographic properties. PHP tracks this issue as bug #81738.

Per MITRE CWE-190: The product performs a calculation that can produce an integer overflow or wraparound when the logic assumes that the resulting value will always be larger than the original value.

This issue affects PHP 7.4 before 7.4.33, PHP 8.0 before 8.0.25 and PHP 8.1 before 8.1.12, which bundle the vulnerable Keccak code, as well as the End-of-Life release lines PHP 7.2 and 7.3 through their final releases (7.2.34 and 7.3.33), which bundle the same code but, as explained below, do not expose the overflow through their hash API.

Details

Module Info

Vulnerability Info

This vulnerability is in the Keccak XKCP SHA-3 reference implementation before commit fdc6fef, which PHP bundles in its hash extension. PHP fixed its copy in 7.4.33, 8.0.25 and 8.1.12; the End-of-Life PHP 7.2 and 7.3 lines carry the same code and never received that fix. The CVE record, assigned by MITRE, has no CNA score; CISA-ADP scores it 9.8, Critical, under CVSS 3.1 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) and classifies it as CWE-190, Integer Overflow or Wraparound. That score describes the library flaw in general; as explained below, PHP 7.2's own hash API does not reach it.

A SHA-3 hash absorbs input into a sponge state in blocks. When input arrives in pieces, for example through repeated hash_update() calls, SpongeAbsorb() keeps the number of bytes already buffered in byteIOIndex and copies the next piece into the state after them. Before the fix, it sized that piece with 32-bit arithmetic:

/* normal lane: using the message queue */
partialBlock = (unsigned int)(dataByteLen - i);
if (partialBlock+instance->byteIOIndex > rateInBytes)
    partialBlock = rateInBytes-instance->byteIOIndex;

When the remaining input is close to 4 GiB, partialBlock + byteIOIndex wraps around in an unsigned int, the size check passes, and SnP_AddBytes() writes far more data into the 200-byte state than it can hold. The upstream report shows this crashing PHP when one byte is passed to hash_update() on a SHA-3 context, followed by a string of 4,294,967,295 bytes.

On PHP 7.4 and later, an application that hashes attacker-supplied data of that size with a SHA-3 algorithm, through hash() or hash_update(), can be affected, provided memory_limit and request size limits allow a string of about 4 GiB. HeroDevs' analysis of PHP 7.2 found that the overflow is not reachable there as shipped: PHP 7.2's hash update functions take an unsigned int length and pass the sponge less than 2^29 bytes per call, so the sum cannot wrap. NES for PHP 7.2 carries the fix anyway, because correcting that length handling, as PHP 7.4 did, would make the overflow reachable.

The fix compares lengths in size_t before narrowing them, so the size of each piece is always capped at the space left in the block:

/* normal lane: using the message queue */
if (dataByteLen-i > rateInBytes-instance->byteIOIndex)
    partialBlock = rateInBytes-instance->byteIOIndex;
else
    partialBlock = (unsigned int)(dataByteLen - i);

Mitigation

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

Until an upgrade is possible on PHP 7.4 or later, avoid hashing untrusted inputs of several gigabytes with SHA-3 algorithms, and keep memory_limit and post_max_size well below the sizes needed to reach the overflow.

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

  • Upgrade to PHP 7.4.33, 8.0.25, 8.1.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
Critical
ID
CVE-2022-37454
PROJECT Affected
PHP
Versions Affected
>=7.2.0 <7.4.33, >=8.0.0 <8.0.25, >=8.1.0 <8.1.12
NES Versions Affected
Published date
October 21, 2022
≈ Fix date
October 27, 2022
Fixed in
Category
Integer Overflow or Wraparound
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.