Pimcore Platform - SQL Injection in DataObject composite index handling during class definition import/save (CVE-2026-5394)
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](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 1. Source: - `Pimcore\Model\DataObject\ClassDefinition\Service::importClassDefinitionFromJson()` accepts `compositeIndices` directly from imported JSON. 2. 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 `__id` and `__type`, which is not a security control. 3. Sink: - `Pimcore\Model\DataObject\Traits\CompositeIndexTrait::updateCompositeIndices()` builds raw SQL with string concatenation and executes it via `$this->db->executeQuery(...)`. 4. Missing protection: - `quoteIdentifier()` is used for the `SHOW INDEXES` query, but not for the dynamic `ALTER TABLE` statements. - No server-side schema validation restricts `index_key` or `index_columns` to known safe identifier characters. ### Confirmed source-to-sink path 1. `importClassDefinitionFromJson()` decodes attacker-controlled JSON and forwards `compositeIndices`. 2. `setCompositeIndices()` stores those values without sanitizing identifier content. 3. `ClassDefinition::save()` reaches `ClassDefinition\Dao::update()`. 4. `Dao::update()` calls `updateCompositeIndices()` for: - `object_store_<classId>` - `object_query_<classId>` 5. `Localizedfield\Dao` also calls `updateCompositeIndices()` for: - localized query tables - localized store tables ### Why this is exploitable The vulnerable `ADD INDEX` statement is built as: ```php '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: ```text slider), DROP COLUMN `oo_className` -- ``` produces SQL of the form: ```sql 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. ### 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-137` - `models/DataObject/ClassDefinition.php:994-1006` - `models/DataObject/Traits/CompositeIndexTrait.php:30-85` - `models/DataObject/ClassDefinition/Dao.php:217-218` - `models/DataObject/Localizedfield/
AI Analysis
Technical Summary
The vulnerability arises from the Pimcore\Model\DataObject\ClassDefinition\Service::importClassDefinitionFromJson() method accepting compositeIndices from imported JSON without strict validation. These values are stored without an allowlist in setCompositeIndices() and later used verbatim in dynamically constructed ALTER TABLE ADD INDEX statements in updateCompositeIndices(), executed via Doctrine DBAL without quoting identifiers. The injection vector is primarily through compositeIndices.index_columns, which is inserted directly into the index column list in the SQL statement. This allows an authenticated admin user to inject additional ALTER TABLE subclauses, such as DROP COLUMN, within a single ALTER TABLE statement, enabling unauthorized schema changes on Pimcore object query and store tables. The vulnerability does not rely on stacked queries and affects the integrity and availability of backend data storage.
Potential Impact
An authenticated administrative user with permission to import or save DataObject class definitions can exploit this vulnerability to execute arbitrary SQL DDL commands on Pimcore object tables. This can result in unauthorized schema modifications, including dropping columns, which may cause backend denial of service by breaking expected table layouts and compromise data integrity of DataObject storage and queries. The impact is limited to users with administrative privileges capable of importing or saving class definitions.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is released, restrict import and save operations of DataObject class definitions to fully trusted administrators only. Avoid importing untrusted JSON definitions containing compositeIndices. Monitor vendor communications for patches addressing proper validation and quoting of composite index metadata in SQL statements.
Pimcore Platform - SQL Injection in DataObject composite index handling during class definition import/save (CVE-2026-5394)
Description
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](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 1. Source: - `Pimcore\Model\DataObject\ClassDefinition\Service::importClassDefinitionFromJson()` accepts `compositeIndices` directly from imported JSON. 2. 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 `__id` and `__type`, which is not a security control. 3. Sink: - `Pimcore\Model\DataObject\Traits\CompositeIndexTrait::updateCompositeIndices()` builds raw SQL with string concatenation and executes it via `$this->db->executeQuery(...)`. 4. Missing protection: - `quoteIdentifier()` is used for the `SHOW INDEXES` query, but not for the dynamic `ALTER TABLE` statements. - No server-side schema validation restricts `index_key` or `index_columns` to known safe identifier characters. ### Confirmed source-to-sink path 1. `importClassDefinitionFromJson()` decodes attacker-controlled JSON and forwards `compositeIndices`. 2. `setCompositeIndices()` stores those values without sanitizing identifier content. 3. `ClassDefinition::save()` reaches `ClassDefinition\Dao::update()`. 4. `Dao::update()` calls `updateCompositeIndices()` for: - `object_store_<classId>` - `object_query_<classId>` 5. `Localizedfield\Dao` also calls `updateCompositeIndices()` for: - localized query tables - localized store tables ### Why this is exploitable The vulnerable `ADD INDEX` statement is built as: ```php '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: ```text slider), DROP COLUMN `oo_className` -- ``` produces SQL of the form: ```sql 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. ### 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-137` - `models/DataObject/ClassDefinition.php:994-1006` - `models/DataObject/Traits/CompositeIndexTrait.php:30-85` - `models/DataObject/ClassDefinition/Dao.php:217-218` - `models/DataObject/Localizedfield/
CVSS v4.0
Affected software
Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.
Weaknesses
AI-Powered Analysis
Machine-generated threat intelligence
Technical Analysis
The vulnerability arises from the Pimcore\Model\DataObject\ClassDefinition\Service::importClassDefinitionFromJson() method accepting compositeIndices from imported JSON without strict validation. These values are stored without an allowlist in setCompositeIndices() and later used verbatim in dynamically constructed ALTER TABLE ADD INDEX statements in updateCompositeIndices(), executed via Doctrine DBAL without quoting identifiers. The injection vector is primarily through compositeIndices.index_columns, which is inserted directly into the index column list in the SQL statement. This allows an authenticated admin user to inject additional ALTER TABLE subclauses, such as DROP COLUMN, within a single ALTER TABLE statement, enabling unauthorized schema changes on Pimcore object query and store tables. The vulnerability does not rely on stacked queries and affects the integrity and availability of backend data storage.
Potential Impact
An authenticated administrative user with permission to import or save DataObject class definitions can exploit this vulnerability to execute arbitrary SQL DDL commands on Pimcore object tables. This can result in unauthorized schema modifications, including dropping columns, which may cause backend denial of service by breaking expected table layouts and compromise data integrity of DataObject storage and queries. The impact is limited to users with administrative privileges capable of importing or saving class definitions.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is released, restrict import and save operations of DataObject class definitions to fully trusted administrators only. Avoid importing untrusted JSON definitions containing compositeIndices. Monitor vendor communications for patches addressing proper validation and quoting of composite index metadata in SQL statements.
Technical Details
- Gcve Source
- db.gcve.eu
- Osv Id
- GHSA-r2f4-ff2p-xc64
- Osv Schema Version
- 1.4.0
- Aliases
- ["CVE-2026-5394"]
- Ecosystems
- ["Packagist"]
- Database Specific Severity
- HIGH
- Cvss Version
- 4.0
Threat ID: 6a520eb868715ace438f55e6
Added to database: 07/11/2026, 09:36:56 UTC
Last enriched: 07/11/2026, 09:51:32 UTC
Last updated: 07/31/2026, 19:22:59 UTC
Views: 53
Community Reviews
0 reviewsCrowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.
Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.
Actions
Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.
Need more coverage?
Upgrade to Pro Console for AI refresh and higher limits.
For incident response and remediation, OffSeq services can help resolve threats faster.
Latest Threats
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.