CVE-2024-3096

Weak Authentication
Affects
PHP
in
PHP
No items found.
Versions
<8.1.28, >=8.2.0 <8.2.18, >=8.3.0 <8.3.5

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 password_hash() function is the standard way for PHP applications to store and check user passwords, with bcrypt as the default algorithm.

An Authentication Bypass vulnerability (CVE-2024-3096) has been identified in PHP's bcrypt support for password_hash(), which allows an attacker to log in with an empty password to an account whose stored password was hashed from a value starting with a NUL byte. PHP tracks this issue as GHSA-h746-cjrr-wfmr.

Per MITRE CWE-287: When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.

This issue affects PHP 8.1 before 8.1.28, PHP 8.2 before 8.2.18 and PHP 8.3 before 8.3.5, as well as all releases of the End-of-Life PHP 5.6 through 8.0 release lines.

Details

Module Info

Vulnerability Info

This Medium-severity vulnerability is found in the password hashing functions of PHP 8.1 before 8.1.28, 8.2 before 8.2.18 and 8.3 before 8.3.5, and in the End-of-Life PHP 5.6 through 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:L/PR:N/UI:R/S:U/C:H/I:N/A:N).

For bcrypt, password_hash() builds a salt string and passes the password to PHP's crypt implementation. A PHP string can contain NUL bytes, but bcrypt reads the password as a C string, so it stops at the first NUL. In PHP 7.4.33 the hashing function passes the password through without looking at its contents:

/* This cast is safe, since both values are defined here in code and cannot overflow */
result = php_crypt(ZSTR_VAL(password), (int)ZSTR_LEN(password), ZSTR_VAL(hash), (int)ZSTR_LEN(hash), 1);
zend_string_release_ex(hash, 0);

A password that starts with a NUL byte is therefore hashed exactly like the empty string. When that hash is later checked, password_hash() computes the same hash for an empty password and returns true. More generally, anything after the first NUL byte in a bcrypt password is ignored.

Exploitation needs an application that lets an attacker choose a password containing a leading NUL byte and hashes it with PASSWORD_BCRYPT or PASSWORD_DEFAULT, for example at registration or password reset, and a login form that accepts an empty password. The attacker, or anyone else, can then sign in to that account without knowing the password. Any SAPI is affected, since ext/standard is always built. Applications that reject empty passwords at login, or that do not accept binary input in passwords, limit the impact, and hashes created with Argon2 are not affected.

The fix, by Jakub Zelenka, makes password_hash() refuse bcrypt passwords that contain a NUL byte. Upstream PHP 8 throws a ValueError. The NES releases refuse such passwords too; on PHP 5.6, 7.2 and 7.4 they emit a warning and return NULL instead of throwing, matching how those versions report other password_hash() errors. The upstream check reads:

if (memchr(ZSTR_VAL(password), '\0', ZSTR_LEN(password))) {
    zend_value_error("Bcrypt password must not contain null character");
    return NULL;
}

Mitigation

The PHP project publishes security fixes only for its supported release lines. PHP 5.6, 7.0, 7.1, 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, reject passwords that contain NUL bytes before passing them to password_hash(), and reject empty passwords at login.

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

  • Upgrade to PHP 8.1.28, 8.2.18, 8.3.5, 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-2024-3096
PROJECT Affected
PHP
Versions Affected
<8.1.28, >=8.2.0 <8.2.18, >=8.3.0 <8.3.5
NES Versions Affected
Published date
April 29, 2024
≈ Fix date
April 11, 2024
Fixed in
Category
Weak Authentication
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.