CVE-2023-0567

Weak Authentication
Affects
PHP
in
PHP
No items found.
Versions
<8.0.28, >=8.1.0 <8.1.16, >=8.2.0 <8.2.3

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.

An Authentication Bypass vulnerability (CVE-2023-0567) has been identified in PHP's bcrypt implementation behind crypt() and password_verify(), which allows an attacker who can place a malformed bcrypt hash in an application's password store to log in to that account with any password. A related flaw lets a two-byte hash make crypt() read past the end of the string. PHP tracks this issue as bug #81744 and GHSA-7fj2-8x79-rjf4.

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 all versions of PHP before 8.0.28, PHP 8.1 before 8.1.16 and PHP 8.2 before 8.2.3, which includes every release of the End-of-Life PHP 5.6 and 7.0 through 7.4 release lines.

Details

Module Info

Vulnerability Info

This High-severity vulnerability is found in the standard extension of all versions of PHP before 8.0.28, PHP 8.1 before 8.1.16 and PHP 8.2 before 8.2.3, including the End-of-Life PHP 5.6 and 7.0 through 7.4 release lines, which never received the upstream fix. The PHP project scores it 7.7 under CVSS 3.1 (CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N). CISA-ADP rates it 8.1 with an adjacent-network attack vector.

A bcrypt hash such as $2y$10$... carries a cost and a 22-character salt, and password_verify() checks a password by hashing it again with that salt and comparing the result to the stored hash. PHP's copy of the crypt_blowfish library differs from the upstream Openwall code by a "PHP hack": the salt decoder stops at a $ character and fills the rest of the salt with zeros. In PHP 7.4.33 the decoder reads:

#define BF_safe_atoi64(dst, src) \
{ \
    tmp = (unsigned char)(src); \
    if (tmp == '$') break; /* PHP hack */ \
    if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
    tmp = BF_atoi64[tmp]; \
    if (tmp > 63) return -1; \
    (dst) = tmp; \
}

A hash whose salt is cut short by a $ is not a valid bcrypt hash, but PHP accepted it. For some of these malformed hashes, crypt() returns the hash string itself, so password_verify(), or code that compares the output of crypt() with the stored value, reports a match for any password. The reporter demonstrated this with a hash of the form $2y$10$am$2y$10$am. A second flaw in php_crypt() let a two-byte $2 hash make PHP read past the end of the string before it checked the length.

Exploitation needs a malformed Blowfish hash to end up in the password store, for example through imported or migrated hashes, or by an attacker who can write a hash value for an account. The application then accepts any password for that account. Any SAPI is affected, the code is part of the always-built standard extension, and OPcache does not change this. Correctly generated hashes, such as those produced by password_hash(), are not affected.

The fix, by Tim Düsterhus, removes the PHP hack so a salt containing $ is rejected and crypt() fails for such hashes, and adds a length check before php_crypt() reads the hash prefix. NES for PHP carries both changes to PHP 5.6, 7.2 and 7.4.

Mitigation

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

Until an upgrade is possible, verify that every stored password hash is well formed before trusting it, and do not import password hashes from untrusted sources.

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

  • Upgrade to PHP 8.0.28, 8.1.16, 8.2.3, 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-2023-0567
PROJECT Affected
PHP
Versions Affected
<8.0.28, >=8.1.0 <8.1.16, >=8.2.0 <8.2.3
NES Versions Affected
Published date
February 16, 2023
≈ Fix date
February 14, 2023
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.