Summary
Pimcore Platform - SQL Injection in DataObject composite index handling during class definition import/save
My name is Oscar Uribe, Security Researcher at Fluid Attacks. I am reaching out because we have identified a security vulnerability in Pimcore 12.3.3 that we would like to report to you so we can coordinate a responsible disclosure together.
As part of our standard disclosure measures, we follow a timeline (outlined at https://fluidattacks.com/advisories/policy), which is aligned with ISO/IEC 29147:2018 and ISO/IEC 30111:2019. In short, the timeline works as follows: we ask for acknowledgment of the report within a few days of your first accessing it, and from there, we are happy to coordinate a joint disclosure date with you, typically within 90 days of the initial discovery. This gives your team reasonable time to assess, develop, and release a fix.
We have reserved the CVE ID "CVE-2026-5394" for this issue, and the advisory will eventually be published at https://fluidattacks.com/advisories/dragons. We are committed to coordinating the timing of that publication with you.
Please feel free to reach out if you have any questions about the report, the process, or the timeline. We are glad to work with you on this.
Description
An authenticated administrative user who can import or save DataObject class definitions can inject attacker-controlled composite index metadata and trigger unintended SQL execution in the backend.
The vulnerable flow accepts compositeIndices from imported JSON, stores the values without strict validation, and later concatenates them directly into ALTER TABLE ... DROP INDEX and ALTER TABLE ... ADD INDEX statements executed through Doctrine DBAL.
Although the original report focused on compositeIndices.index_key, independent code review shows that the strongest and most reliable injection point is compositeIndices.index_columns, because it is inserted verbatim inside the ADD INDEX (...) clause. This permits injection of additional ALTER TABLE subclauses against Pimcore object tables without relying on stacked queries.
Vulnerability
Root cause
- Source:
Pimcore\Model\DataObject\ClassDefinition\Service::importClassDefinitionFromJson()acceptscompositeIndicesdirectly from imported JSON.
- Assignment:
Pimcore\Model\DataObject\ClassDefinition::setCompositeIndices()does not enforce an allowlist for index names or column names.- The only special handling is a ManyToOne relation rewrite to
__idand__type, which is not a security control.
- Sink:
Pimcore\Model\DataObject\Traits\CompositeIndexTrait::updateCompositeIndices()builds raw SQL with string concatenation and executes it via$this->db->executeQuery(...).
- Missing protection:
quoteIdentifier()is used for theSHOW INDEXESquery, but not for the dynamicALTER TABLEstatements.- No server-side schema validation restricts
index_keyorindex_columnsto known safe identifier characters.
Confirmed source-to-sink path
importClassDefinitionFromJson()decodes attacker-controlled JSON and forwardscompositeIndices.setCompositeIndices()stores those values without sanitizing identifier content.ClassDefinition::save()reachesClassDefinition\Dao::update().Dao::update()callsupdateCompositeIndices()for:object_store_<classId>object_query_<classId>
Localizedfield\Daoalso callsupdateCompositeIndices()for:- localized query tables
- localized store tables
Why this is exploitable
The vulnerable ADD INDEX statement is built as:
'ALTER TABLE `'.$table.'` ADD INDEX `' . $key.'` ('.$columnName.');'
$columnName is produced from implode(',', $columns) and is not quoted or validated. A malicious index_columns element such as:
slider), DROP COLUMN `oo_className` --
produces SQL of the form:
ALTER TABLE `object_query_<id>` ADD INDEX `c_poc_idx` (slider), DROP COLUMN `oo_className` -- );
This remains a single ALTER TABLE statement, so the base vulnerability does not depend on multi-statement support. The attacker can inject additional DDL clauses affecting the target Pimcore object table.
PoC
Application-level PoC
Preconditions:
- valid authenticated administrative session
- ability to import or save a class definition containing
compositeIndices
The original report reproduced the issue through an authenticated Studio endpoint:
POST /pimcore-studio/api/class/definition/configuration-view/detail/1/import
Minimal malicious JSON fragment:
{
"compositeIndices": [
{
"index_key": "poc_idx",
"index_type": "query",
"index_columns": [
"slider), DROP COLUMN `oo_className` -- "
]
}
]
}
Reproduction:
- Authenticate as an administrator with permission to manage/import class definitions.
- Export an existing class definition or prepare a valid class-definition JSON document.
- Replace only the
compositeIndicessection with the payload above. - Import the modified definition or save the class through the administrative workflow.
Expected result:
- Pimcore reaches
updateCompositeIndices()during class save/import. - The backend executes an attacker-influenced
ALTER TABLEstatement against the target object table. - The affected class table is modified unexpectedly, for example by dropping a column or otherwise changing schema.
Minimal source-level confirmation
The behavior is directly visible from the code path:
$newIndicesMap['c_' . $key] = implode(',', $columns);
$columnName = $newIndicesMap[$key];
$this->db->executeQuery(
'ALTER TABLE `'.$table.'` ADD INDEX `' . $key.'` ('.$columnName.');'
);
No escaping or allowlist validation is applied to $columns before they are interpolated into SQL.
Evidence of Exploitation
- Video of exploitation:
https://github.com/user-attachments/assets/64a49147-12a5-4550-ba22-cb4383523557
- Static evidence:
Our security policy
We have reserved the ID CVE-2026-5394 to refer to this issue from now on.
System Information
Pimcore Platform
Version v12.3.3
Database layer: doctrine/dbal ^4.4
Operating System: Any
References
Github Repository: https://github.com/pimcore/pimcore
Security: https://github.com/pimcore/pimcore/security
Impact
The issue allows a privileged attacker to alter backend SQL behavior during class-definition import/save and modify schema on Pimcore object tables associated with the affected class.
Practical impact includes:
- unauthorized schema modification on object query/store tables
- backend denial of service by breaking expected table layout
- data integrity impact for DataObject storage and queries
index_key is also concatenated into SQL without proper identifier escaping, but the most defensible exploitation path is through index_columns.
Relevant code:
models/DataObject/ClassDefinition/Service.php:92-137models/DataObject/ClassDefinition.php:994-1006models/DataObject/Traits/CompositeIndexTrait.php:30-85models/DataObject/ClassDefinition/Dao.php:217-218models/DataObject/Localizedfield/Dao.php:945-951
Untrusted input alters a database query, allowing the attacker to read or modify data the query was not intended to access. Typical impact: data disclosure or modification.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Already deployed Kodem?
See it in your environmentNew to Kodem? Get a demo →Remediation advice
pimcore/pimcore to 12.3.7 or later; pimcore/pimcore to 11.5.17 or later; pimcore/pimcore to 2026.1.3 or later
Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.
Frequently Asked Questions
- What is CVE-2026-5394? CVE-2026-5394 is a high-severity SQL injection vulnerability in pimcore/pimcore (composer), affecting versions >= 12.0.0-RC1, <= 12.3.6. It is fixed in 12.3.7, 11.5.17, 2026.1.3. Untrusted input alters a database query, allowing the attacker to read or modify data the query was not intended to access.
- Which versions of pimcore/pimcore are affected by CVE-2026-5394? pimcore/pimcore (composer) versions >= 12.0.0-RC1, <= 12.3.6 is affected.
- Is there a fix for CVE-2026-5394? Yes. CVE-2026-5394 is fixed in 12.3.7, 11.5.17, 2026.1.3. Upgrade to this version or later.
- Is CVE-2026-5394 exploitable, and should I be worried? Whether CVE-2026-5394 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-5394 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-5394?
- Upgrade
pimcore/pimcoreto 12.3.7 or later - Upgrade
pimcore/pimcoreto 11.5.17 or later - Upgrade
pimcore/pimcoreto 2026.1.3 or later
- Upgrade