Zero byte broke PHP protection and opened the way to SQL injection

Depov

Moderator
Staff member
MODERATOR
ULTIMATE
SUPREME
PREMIUM
MEMBER
Joined
Feb 18, 2025
Messages
242
Reaction score
305
Deposit
0$
Positive Technologies researchers found in PHP two errors at the junction of the usual code of web applications and low-level database drivers. One vulnerability opened the way to SQL injection in the Firebird driver through a zero byte in the row, and the other could drop the PHP process when working with PostgreSQL. Both issues affected PDO, a standard PHP layer for working with different databases through a single interface.





PDO uses thousands of applications: the developer writes queries through a familiar object API, and a particular driver transmits the MySQL, PostgreSQL, Firebird, SQLite commands or other DBMS. Convenient abstraction hides many low-level parts. The study found that errors in the processing of lines inside drivers can break even the security mechanisms that developers have been accustomed to trust for years.





The first vulnerability received the CVE-2025-14179 identifier and a high level of danger. The problem was in pdo_firefield, the PDO driver for Firebird. Researchers Alexey Solovyov and Nikita Sveshnikov found out that the PDO shielding function::quote correctly processed special symbols and zero bytes, but the subsequent preparation of the SQL query in PDO:preprere broke the structure of the line.





The error occurred during the re-extortion and assembly of the SQL query inside the Firebird driver. The driver used a strncat() function that in C perceives a zero byte as the end of the line. If the user input contained \0, the driver cut the string literal and lost the closing-pit. After the boundary was lost, the query fragments, which were to remain regular data, could get into the executable SQL text.









In practice, the attack required a specific code template: the application first shielded user input through PDO::quote, then inserted the result into a dynamic SQL query and transmitted the finished line to PDO:prepare. Many developers consider this approach to be safe because the input goes through a regular shielding mechanism. In the case of pdo_firefield, the protection was broken later, already during the internal preparation of the request by the driver.





In the demonstration, the researchers showed how a zero byte in the username and the specially selected value of the second parameter allowed to perform UNION SELECT and obtain Firebird service data, including the version of the database engine. Instead of an empty result, the application returned entries from the user table and system information. Supporting PHP developers closed CVE-2025-14179 in May 2026, replacing the insecure assembly of lines with binary-safe processing of fragments, taking into account the actual data length.





The second vulnerability was received by the CVE-2025-14180 identifier and a score of 6.3 points out of ten. The problem affected pdo_pgsql when working with PostgreSQL, if the application clearly included emulation of prepared expressions via PDO: ATTR_EMULATE_PREPARES. In this mode, PDO produced emulation at the level of the language rather than the DBMS: substituted the parameters in the SQL query template, shielded the values on the PHP side and sent the server a ready-made SQL query.





The failure occurred in the abstract PDO extension when transferring the parameter with an unacceptable multibyte sequence for the current coding of the connection. The PostgreSQL libpq client library reported a shielding error, the driver pdo_pgsql returned NULL, and the PDO parser continued to refer to the result as a regular line. The Zend Engine macro tried to read the length of the line at zero pointer, after which the operating system completed the PHP process with a segmentation error.





For a web application, such a failure means service failure: PHP tvorker is being crashed, and the try/catch block will not be called and will not be able to process the exception. The researchers separately showed a business risk on the example of a conditional service for the sale of digital licenses. The application managed to write off money from the user balance, then fell when saving a comment to the order with an incorrect byte. The record of the order was not created, the warehouse balance did not change, the account was not formed, and the user saw the backend error.





The danger is amplified in multi-step operations without explicit transactions. If the application relies on a car committee, some of the changes may get into the database before the process fall, and subsequent actions will not be performed. In a distributed architecture, a similar failure is able to leave different services in an uncoordinated state, especially if before the emergency completion of the component has already sent an external request or recorded an intermediate operation.





PHP developers fixed CVE-2025-14180 on December 16, 2025. The correction added a screening test before turning to the line length. When an error, the PDO driver now returns the usual application layer error instead of the emergency completion of the process. To protect, the researchers recommend updating PHP at least to 8.1.34, 8.2.30, 8.3.29, 8.4.16 or 8.5.1. To protect against SQL injection in pdo_firebird, you need to upgrade PHP to 8.2.31, 8.3.31, 8.4.21, 8.5.6 or newer for the Null Pointer Deference.





Both vulnerabilities show that the security of PHP applications depends not only on the developer code, but also on the rent, extensions and language drivers. Even the usual shielding mechanisms and prepared expressions can fail on rare input data if the low-level part of the stack is incorrectly processed bytes, strings or errors. Practical protection is reduced to a timely update of PHP, refusal of unnecessary emibling of prepared expressions, careful processing of binary input and mandatory transactions for financial, warehouse and other multi-step operations.
 
Top Bottom