CVE-2023-3247

Cryptographic Weakness
Affects
PHP
in
PHP
No items found.
Versions
<8.0.29, >=8.1.0 <8.1.20, >=8.2.0 <8.2.7

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 soap extension provides the SoapClient class, which can authenticate to SOAP services over HTTP Basic or Digest authentication.

A Cryptographic Weakness vulnerability (CVE-2023-3247) has been identified in the HTTP Digest authentication code of PHP's SoapClient, which allows a malicious or compromised SOAP server to guess the client nonce more easily, making offline guessing of the client's password easier, and, if the system's random source fails, to receive up to 31 bits of uninitialized memory from the client. PHP tracks this issue as GHSA-76gg-c692-v2mw.

Per MITRE CWE-330: The product uses insufficiently random numbers or values in a security context that depends on unpredictable numbers.

This issue affects PHP 8.0 before 8.0.29, PHP 8.1 before 8.1.20 and PHP 8.2 before 8.2.7, as well as all releases of the End-of-Life PHP 5.6 through 7.4 release lines.

Details

Module Info

Vulnerability Info

This Low-severity vulnerability is found in the soap extension of PHP 8.0 before 8.0.29, 8.1 before 8.1.20 and 8.2 before 8.2.7, and in the End-of-Life PHP 5.6 through 7.4 release lines, which never received the upstream fix. The PHP project scores it 2.6 under CVSS 3.1 (CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:N/A:N).

In HTTP Digest authentication the client mixes a random client nonce (cnonce) into the hash it sends, so that a malicious server cannot answer with a fixed server nonce and look the response up in a precomputed table of passwords. In PHP 7.4.33, SoapClient builds that nonce as follows:

char HA1[33], HA2[33], response[33], cnonce[33], nc[9];
zend_long nonce;
PHP_MD5_CTX md5ctx;
unsigned char hash[16];

php_random_bytes_throw(&nonce, sizeof(nonce));
nonce &= 0x7fffffff;

PHP_MD5Init(&md5ctx);
snprintf(cnonce, sizeof(cnonce), ZEND_LONG_FMT, nonce);
PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, strlen(cnonce));
PHP_MD5Final(hash, &md5ctx);
make_digest(cnonce, hash);

Two problems follow. The nonce is masked to 31 random bits, and the upstream fix notes that a server precomputing responses for only 2^14 nonces would still have about a 10% chance of reversing a password from a single request. And the return value of php_random_bytes_throw() is ignored, so if the system's random source fails, the uninitialized stack variable is used instead; hashing it with MD5 does not hide it, because 31 bits are easy to enumerate. HeroDevs' analysis found the same predictable-nonce weakness in PHP 5.6.

Exploitation needs a SoapClient created with login and password that talks to a malicious or compromised server, which answers with a WWW-Authenticate: Digest challenge; the client does not need to be configured for Digest explicitly. Any SAPI is affected, including command-line scripts. The memory disclosure also needs the system's random source to fail. Applications that do not use SoapClient with credentials, or only talk to trusted servers, are not exposed.

The fix, by Nora Dossche with Tim Düsterhus, draws the nonce from 16 random bytes and aborts the request if the random source fails. The NES for PHP 5.6 fix also sends all 128 bits of the nonce instead of the first eight hex characters. The upstream fix commit reads:

unsigned char nonce[16];
PHP_MD5_CTX md5ctx;
unsigned char hash[16];

if (UNEXPECTED(php_random_bytes_throw(&nonce, sizeof(nonce)) != SUCCESS)) {
    ZEND_ASSERT(EG(exception));
    php_stream_close(stream);
    convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr));
    convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr));
    convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr));
    smart_str_free(&soap_headers_z);
    smart_str_free(&soap_headers);
    return FALSE;
}

php_hash_bin2hex(cnonce, nonce, sizeof(nonce));
cnonce[32] = 0;

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, use SoapClient credentials only with trusted SOAP servers over HTTPS, and prefer services that do not use HTTP Digest authentication.

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

  • Upgrade to PHP 8.0.29, 8.1.20, 8.2.7, 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
Low
ID
CVE-2023-3247
PROJECT Affected
PHP
Versions Affected
<8.0.29, >=8.1.0 <8.1.20, >=8.2.0 <8.2.7
NES Versions Affected
Published date
July 22, 2023
≈ Fix date
June 8, 2023
Fixed in
Category
Cryptographic Weakness
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.