CVE-2026-55416: Pimcore Custom Reports SQL Injection via Report Configuration Fields
An authenticated Pimcore admin with report-configuration permission can inject arbitrary SQL through report fields that are concatenated directly into queries, exposing the entire database.

The problem
The SQL adapter in Pimcore's CustomReportsBundle (bundles/CustomReportsBundle/src/Tool/Adapter/Sql.php) concatenates user-controlled report configuration fields, sql, from, where, and groupby, directly into raw SQL strings with no parameterization.
The only guard is a regex blacklist blocking ALTER|CREATE|DROP|RENAME|TRUNCATE|UPDATE|DELETE. It misses INSERT, UNION SELECT, LOAD_FILE(), INTO OUTFILE, subqueries, and MySQL comment injection (/*!*/), making bypass trivial. A secondary injection point exists at the LIMIT clause, where $offset and $limit are interpolated without integer casting.
Successful exploitation gives full read, write, and delete access to the database.
Proof of concept
A working proof-of-concept for CVE-2026-55416 in pimcore/pimcore, with the exact payload below.
POST /admin/bundle/customreports/custom-report/update HTTP/1.1
Host: <target>
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=<valid_admin_session>
name=malicious_report&configuration={"sql":"","from":"users","where":"1=1 UNION SELECT TABLE_NAME,TABLE_SCHEMA,3 FROM INFORMATION_SCHEMA.TABLES-- -","groupby":"","dataSourceConfig":{}}The buildQueryString() method (lines 84-135) performs direct string concatenation: $sql .= "\n" . $config['where'], so the attacker-controlled where value closes the intended WHERE ( wrapper and appends a UNION SELECT that reads from INFORMATION_SCHEMA.TABLES, enumerating all database tables.
Because the blacklist does not include UNION or SELECT, the regex check at line ~120 passes without a match.
The LIMIT injection is a separate but related path: $sql .= ' LIMIT ' . $offset . ',' . $limit without (int) casts, so a crafted offset like 0; SELECT user()-- - stacks a second query. The patch closes both paths by replacing concatenation with parameterized queries or strict integer casts, and by extending the keyword blacklist to cover all bypass vectors.
The fix
Upgrade to Pimcore 2026.1.6 (or 12.3.10 / 11.5.19 on older branches). The fix replaces raw string concatenation in buildQueryString() with a parameterized query-builder approach and casts $offset and $limit to integers ((int)$offset, (int)$limit) before interpolation.
Until you can upgrade, remove reports_config permission from any user who does not strictly need it.
Related research
- critical · 9.9CVE-2026-55634CVE-2026-55634: Pimcore DataObject Field Name Remote Code Execution and SQL Injection
- high · 8.5CVE-2026-55072CVE-2026-55072: Pimcore ClassDefinition UID Regex Missing End Anchor Allows SQL Injection
- criticalCVE-2026-77635CVE-2026-77635: CakePHP FunctionsBuilder::jsonValue() SQL Injection via PostgreSQL Driver
- high · 7.7CVE-2026-55208CVE-2026-55208: Pimcore Studio Backend Bundle SQL Injection via DateFilter Column Key