NULL Pointer Dereference in PDO quoting

Kurzinfo

Metadaten

  • Original (extern): Link oeffnen
  • Veroeffentlicht: 2025-12-18 16:10 UTC
  • Importiert: 2026-10-07 06:38 UTC
  • CVSS: 8.2
  • Quelle-ID: php_sec
  • uid_hash: 544fca703f03023332f39223dd8885fb6b1584bf0bc84b9b2f6152aa842e7258

Inhalt

Product: PHP Version: 8.5.0-DEV (CLI) CWE-ID: CWE-476: NULL Pointer Dereference CVSS vector v.4.0: 8.2 (AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N) Description: A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit. Exploitation conditions: An unauthorized user Mitigation: Explicitly check whether a NULL pointer exists before dereferencing it. Researcher: Aleksey Solovev (Positive Technologies)

Research

The vulnerable source code is the ZSTR_LEN(plc->quoted) macro call in the pdo_parse_params function in php-src/ext/pdo/pdo_sql_parser.re. Inside the ZSTR_LEN(plc->quoted) macro, the len field is accessed.

Figure 1. The ZSTR_LEN macro

However, when using a special character sequence, plc->quoted is equal to 0x0.

Figure 2. The vulnerable source code

The plc->quoted field is generated in this case on line 302 when calling the stmt->dbh->methods->quoter function.

Figure 3. plc->quoted initialization

When calling stmt->dbh->methods->quoter, the quoting function pgsql_handle_quoter for PG will be called. On line 407, it will call the PG library function PQescapeStringConn, which will return an error when processing the special sequence, returning NULL as a result. This result will be assigned to the plc->quoted field.

Figure 4. Returning NULL when error occurs

Vulnerability reproduction

The PHP language was compiled using the following commands.

Listing 1. Compiling PHP

$ git clone https://github.com/php/php-src.git
$ cd php-src
$ ./buildconf
$ ./configure CFLAGS="-fsanitize=address -g" CXXFLAGS="-fsanitize=address -g"
LDFLAGS="-fsanitize=address" --with-pdo-pgsql --enable-debug
$ make -j8
$ ./sapi/cli/php -v
PHP 8.5.0-dev (cli) (built: Sep 22 2025 13:24:35) (NTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.5.0-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.5.0-dev, Copyright (c), by Zend Technologies

Next, the following PHP code was placed on the server, causing to Segmentation fault. Enabling the PDO::ATTR_EMULATE_PREPARES mode is the key element of this code. The problem is caused by a non-existent sequence of characters in hexadecimal notation, for example \x99.

Listing 2. Source code on the server

 true
        ]);

        $sql = "SELECT * FROM users where username = :username";
        $stmt = $pdo->prepare($sql);

        $p1 = "alice\x99";
        $stmt->execute(['username' => $p1]);

        foreach ($stmt as $row) {
            print_r($row);
        }
    } catch (PDOException $e) { echo $e->getMessage(); }
?>

Executing the following PHP code results in Segmentation fault, which leads to Denial of Service (DoS).

Figure 5. Demonstration of the vulnerability

Security impact

If there is no extra validaiton for zero byte of the quoted user input, then it could lead to a potential DoS and for ZTS mode stopping all other currently served requests in the process.

Credits

Aleksey Solovev (Positive Technologies)

Verknuepfte CVEs

CVE-ID Severity (Quelle) CVSS (Quelle) Severity (CVE.org) CVSS (CVE.org) EPSS EPSS-Pctl Veroeffentlicht (CVE.org)

CVE-2025-14180

HIGH

8.2

HIGH

8.2

2025-12-27

Quellen-Details

Bezeichnung Name Kategorie Tags Zielgruppe Sprache Feed-URL
PHP Security (php/php-src GHSA)

php_sec

vendor_advisory php, runtime - de https://github.com/php/php-src/security/advisories