
Pimcore Platform v12.3.3 - SQL Injection in DataObject composite index handling
7
High
Detected by

Fluid Attacks AI SAST Scanner
Disclosed by
Oscar Naveda
Summary
Full name
Pimcore Platform v12.3.3 - SQL Injection in DataObject composite index handling during class definition import/save
Code name
State
Public
Release date
Affected product
Pimcore
Vendor
Pimcore
Affected version(s)
12.3.3
Vulnerability name
Blind-based SQL injection
Vulnerability type
Remotely exploitable
Yes
CVSS v4.0 vector string
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:L/VA:L/SC:N/SI:N/SA:N
CVSS v4.0 base score
7.0
Exploit available
Yes
CVE ID(s)
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 the 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
The vulnerable ADD INDEX statement is built as:
$columnName is produced from implode(',', $columns) and is not quoted or validated. A malicious index_columns element such as:
produces SQL of the form:
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.
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 the 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
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:
Minimal malicious JSON fragment:
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 the schema.
Minimal source-level confirmation
The behavior is directly visible from the code path:
No escaping or allowlist validation is applied $columns before they are interpolated into SQL.
Evidence of Exploitation
Video of exploitation:
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
Operating System: Any
References
Github Repository: https://github.com/pimcore/pimcore
Security: https://github.com/pimcore/pimcore/security
Mitigation
There is currently no patch available for this vulnerability.
Credits
The vulnerability was discovered by Oscar Naveda from Fluid Attacks' Offensive Team using the AI SAST Scanner.
Timeline
Vulnerability discovered
Vendor contacted
Public disclosure
Does your application use this vulnerable software?
During our free trial, our tools assess your application, identify vulnerabilities, and provide recommendations for their remediation.






