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
]);
$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)