CVE-2021-21704

Stack-based Buffer Overflow
Affects
PHP
in
PHP
No items found.
Versions
<7.3.29, >=7.4.0 <7.4.21, >=8.0.0 <8.0.8

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 PDO extension gives applications one database API across drivers, and the pdo_firebird driver connects it to Firebird and InterBase database servers.

A Buffer Overflow vulnerability (CVE-2021-21704) has been identified in PHP's PDO Firebird driver, which allows a malicious Firebird server, or an attacker who can impersonate one, to send replies with invalid lengths and strings that overflow a stack buffer or make PHP read outside its buffers, crashing the client process and potentially corrupting memory. PHP tracks these issues as bugs #76448, #76449, #76450 and #76452.

Per MITRE CWE-121: A stack-based buffer overflow condition is a condition where the buffer being overwritten is allocated on the stack (i.e., is a local variable or, rarely, a parameter to a function).

This issue affects PHP before 7.3.29, PHP 7.4 before 7.4.21 and PHP 8.0 before 8.0.8, which includes every End-of-Life release line from PHP 5.6 through 7.2, each through its final release.

Details

Module Info

Vulnerability Info

This Medium-severity vulnerability is found in the pdo_firebird extension of PHP before 7.3.29, 7.4 before 7.4.21 and 8.0 before 8.0.8, including every End-of-Life release line from PHP 5.6 through 7.2, which never received the upstream fix. The PHP project scores it 5.0 under CVSS 3.1 (CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:L) and classifies it as CWE-125, Out-of-bounds Read, and CWE-190, Integer Overflow or Wraparound.

The CVE covers four related bugs in how the driver parses data that the Firebird server sends back. The most serious is in firebird_info_cb(), the callback that builds the server version string for PDO::getAttribute() with PDO::ATTR_SERVER_VERSION or PDO::ATTR_SERVER_INFO. It appends each piece of the server's reply to a 512-byte stack buffer with strcat(), without checking its length. Before the fix, the callback reads:

static void firebird_info_cb(void *arg, char const *s) /* {{{ */
{
    if (arg) {
        if (*(char*)arg) { /* second call */
            strcat(arg, " ");
        }
        strcat(arg, s);
    }
}

A server that returns a long version string therefore overflows the stack buffer in firebird_handle_get_attribute() (bug #76448). The other three bugs are out-of-bounds reads. firebird_handle_doer(), used by PDO::exec(), and firebird_stmt_execute() trusted the result size and item lengths in the server's row count reply, and a negative length could also make the parsing loop run forever (bugs #76449 and #76450). firebird_fetch_blob() trusted the blob length the server reported, and a length of -1 could overflow the size passed to erealloc() (bug #76452). The CVE record describes the result as crashes in functions such as getAttribute(), execute() and fetch(), denial of service, or potentially memory corruption.

Exploitation needs an application that connects with pdo_firebird to a Firebird server the attacker controls, or to a server whose traffic the attacker can intercept and alter. HeroDevs' analysis confirms the same behavior on PHP 5.6 and 7.2, from any server API, when the extension is built. Applications that do not load pdo_firebird, or connect only to trusted Firebird servers over a protected network, are not exposed.

The upstream fixes check every length the server supplies against its buffer. For the version string, the callback now uses strlcat() with the buffer size:

#define INFO_BUF_LEN 512

/* callback to used to report database server info */
static void firebird_info_cb(void *arg, char const *s) /* {{{ */
{
    if (arg) {
        if (*(char*)arg) { /* second call */
            strlcat(arg, " ", INFO_BUF_LEN);
        }
        strlcat(arg, s, INFO_BUF_LEN);
    }
}

Mitigation

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

Until an upgrade is possible, connect only to trusted Firebird servers over a protected network, or disable the pdo_firebird extension if the application does not use it.

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

  • Upgrade to PHP 7.3.29, 7.4.21, 8.0.8, 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-2021-21704
PROJECT Affected
PHP
Versions Affected
<7.3.29, >=7.4.0 <7.4.21, >=8.0.0 <8.0.8
NES Versions Affected
Published date
October 4, 2021
≈ Fix date
June 17, 2021
Fixed in
Category
Stack-based Buffer Overflow
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.