Vulnerability Overview
| Field | Details |
|---|---|
| CVE ID | CVE-2025-14180 |
| Vulnerability Name | NULL Pointer Dereference in PDO Quoting |
| Affected Product | PHP (PDO PostgreSQL Extension) |
| Affected Versions | 8.1.* < 8.1.34, 8.2.* < 8.2.30, 8.3.* < 8.3.29, 8.4.* < 8.4.16, 8.5.* < 8.5.1 |
| Fixed Versions | 8.1.34, 8.2.30, 8.3.29, 8.4.16, 8.5.1 |
| CVSS v4.0 Score | 8.2 (High) |
| GitHub Advisory Score | 6.3 (Moderate) |
| CVSS Vector | AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N |
| Severity | High (Availability Impact) |
| CWE ID | CWE-476 – NULL Pointer Dereference |
| Attack Vector | Network (Remote) |
| Privileges Required | None |
| User Interaction | None |
| Impact | Denial of Service (Application / Process Crash) |
| Exploitability | Remotely exploitable, low operational complexity |
| Exploit Availability | Public Proof-of-Concept available |
| In-the-Wild Exploitation | Not reported at time of disclosure |
| CISA KEV Status | Not listed |
| Publication Date | December 18, 2025 |
| Discovered By | Aleksey Solovev (Positive Technologies) |
Executive Summary
CVE-2025-14180 is a NULL pointer dereference vulnerability affecting PHP applications that use PDO with PostgreSQL when emulated prepared statements are enabled (PDO::ATTR_EMULATE_PREPARES = true).
The issue is triggered when specially crafted input containing invalid character sequences (for example, \x99) is passed as a prepared statement parameter. Under these conditions, the PostgreSQL client library function PQescapeStringConn() fails and returns NULL. PHP’s PDO extension does not properly validate this return value and later dereferences it, resulting in a segmentation fault.
The end result is a crash of the PHP process, making this a pure availability vulnerability. While it does not allow data theft or code execution, it enables unauthenticated remote attackers to reliably crash PHP workers, leading to Denial of Service (DoS). In environments using PHP-FPM or ZTS (Zend Thread Safety), the impact can be amplified, affecting multiple concurrent requests.
Technical Analysis
How the Vulnerability Works
The root cause lies in how PDO handles parameter quoting when PostgreSQL is used with emulated prepared statements.
The execution flow looks like this:
- User Input Handling
A PHP application prepares a SQL query using PDO and binds user-supplied parameters. WhenPDO::ATTR_EMULATE_PREPARESis enabled, PDO escapes parameters itself instead of letting PostgreSQL handle them. - PDO Parameter Parsing
The vulnerable code path resides inpdo_parse_params()withinphp-src/ext/pdo/pdo_sql_parser.re. This function processes bound parameters before query execution. - Quoter Invocation
For PostgreSQL connections, PDO callspgsql_handle_quoter()inpdo_pgsql, which in turn relies on PostgreSQL’sPQescapeStringConn()function to safely escape the input. - Invalid Character Sequences
When the input contains invalid or malformed byte sequences that do not conform to the connection’s character encoding (such as\x99under UTF-8),PQescapeStringConn()fails and returnsNULL. - Missing NULL Check
The returned value is assigned to an internal structure (plc->quoted) without validating whether it is NULL. - Crash Trigger
Later, the macroZSTR_LEN(plc->quoted)is invoked. Sinceplc->quotedis NULL, PHP dereferences a NULL pointer, causing a segmentation fault and immediate process termination.
Vulnerable Code Locations
php-src/ext/pdo/pdo_sql_parser.re- Function:
pdo_parse_params() - Issue: Dereferencing
plc->quotedwithout NULL validation
- Function:
php-src/ext/pdo_pgsql/pgsql_driver.c- Function:
pgsql_handle_quoter() - Issue: Calls
PQescapeStringConn()without checking for failure
- Function:
Conditions Required for Exploitation
For CVE-2025-14180 to be exploitable, all of the following must be true:
- The application uses PDO with the PostgreSQL driver (
pdo_pgsql) PDO::ATTR_EMULATE_PREPARESis enabled (a common default or performance optimization)- User-controlled input is passed as a prepared statement parameter
- Input validation does not filter invalid or non-UTF-8 byte sequences
No authentication or elevated privileges are required.
Proof of Concept (PoC)
NOTE: This is only for educational purpose
<?php
ini_set('memory_limit', '-1');
$dsn = "pgsql:host=localhost;port=5432;dbname=db";
$username = 'manager';
$password = 'password';
try {
$pdo = new PDO($dsn, $username, $password, [
PDO::ATTR_EMULATE_PREPARES => true
]);
$sql = "SELECT * FROM users WHERE username = :username";
$stmt = $pdo->prepare($sql);
$payload = "alice\x99"; // Invalid byte sequence
$stmt->execute(['username' => $payload]);
foreach ($stmt as $row) {
print_r($row);
}
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
Executing this code reliably causes a segmentation fault, crashing the PHP process.
Exploitation Scenarios
Attackers can trigger this vulnerability through any data path that eventually reaches a PDO PostgreSQL query:
- Web Forms and APIs – login forms, search fields, registration endpoints
- URL Parameters – e.g.,
?username=alice%99 - HTTP Headers and Cookies – when logged or stored in the database
- File Upload Metadata – filenames or extracted metadata
- Third-Party Data Imports – external feeds or API integrations
In high-traffic environments, repeated requests can keep crashing PHP workers, creating a sustained denial-of-service condition.
MITRE ATT&CK Mapping
| Tactic | Technique ID | Technique |
|---|---|---|
| Initial Access | T1190 | Exploit Public-Facing Application |
| Impact | T1499 | Endpoint Denial of Service |
| Impact | T1499.004 | Application or System Exploitation |
Mapping Rationale:
The vulnerability allows attackers to exploit a public-facing application using malformed input (T1190), resulting in application crashes and denial of service (T1499 / T1499.004).
Detection and Monitoring
Key Log Sources to Monitor
- PHP Error Logs / PHP-FPM Logs
- Segmentation fault messages,
SIGSEGV, unexpected worker exits
- Segmentation fault messages,
- Web Server Access Logs (Apache / Nginx)
- Requests containing suspicious byte patterns
- PostgreSQL Logs
- Encoding or invalid byte sequence errors
- System Logs (syslog / dmesg)
- PHP process crashes or core dumps
Payload Indicators
Watch for these patterns in request data:
- Raw bytes:
\x99,\x80–\xFF - URL-encoded equivalents:
%99,%C0–%FF - Non-printable or malformed UTF-8 sequences
Example SIEM Detection Logic (Splunk)
index=web_logs sourcetype=access_combined
| regex uri_query="(%[89A-Fa-f][0-9A-Fa-f])|(\\x[89A-Fa-f][0-9A-Fa-f])"
| stats count by src_ip, uri, user_agent
| where count > 5
Example Sigma Rule
title: CVE-2025-14180 PHP PDO PostgreSQL DoS Attempt
status: experimental
logsource:
category: webserver
detection:
selection:
cs-uri-query|contains:
- '%99'
- '%C0'
- '%FF'
condition: selection
level: medium
tags:
- attack.impact
- attack.t1499
- cve.2025.14180
Example WAF / ModSecurity Rule
SecRule ARGS "@rx (%[89A-Fa-f][0-9A-Fa-f]){1,}" \
"id:2025141801,\
phase:2,\
deny,\
status:403,\
log,\
msg:'CVE-2025-14180: Potential PHP PDO PostgreSQL DoS Attempt'"
Mitigation and Remediation
Immediate Mitigations
- Disable emulated prepared statements:
PDO::ATTR_EMULATE_PREPARES => false - Validate input encoding using functions such as
mb_check_encoding() - Deploy WAF rules to block malformed byte sequences
- Monitor PHP-FPM worker stability and restart frequency
Permanent Fix – Apply Official Patches
The PHP project released fixes on December 18, 2025. Upgrade immediately to:
| PHP Branch | Secure Version |
|---|---|
| 8.1.x | 8.1.34 |
| 8.2.x | 8.2.30 |
| 8.3.x | 8.3.29 |
| 8.4.x | 8.4.16 |
| 8.5.x | 8.5.1 |
Official Patch Sources (Only):
- https://www.php.net/downloads.php
- https://windows.php.net/download/
- https://github.com/php/php-src/releases
FinalTakeaway
CVE-2025-14180 is a serious availability vulnerability affecting PHP applications that rely on PostgreSQL through PDO with emulated prepared statements. Although it does not lead to data compromise or code execution, it provides attackers with a reliable, unauthenticated way to crash PHP processes.
Organizations should treat this issue as high priority, apply the official patches immediately, and consider disabling emulated prepares as a long-term hardening measure. Proactive monitoring and input validation remain essential even after patching.
