CVE-2026-5394: Pimcore/pimcore SQL Injection Vulnerability

HIGH
Advisory Identifier: GHSA-r2f4-ff2p-xc64
CWE-89
Published
Advisory Summary

CVE-2026-5394 is a HIGH sql injection vulnerability (CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')) affecting Pimcore/pimcore libraries in the Packagist ecosystem. The issue involves pimcore platform - sql injection in dataobject composite index handling during class definition import/save. Remediation is available by upgrading affected packages to version 12.3.7, 11.5.17, 2026.1.3.

CVE-2026-5394 at a Glance

CVE Identifier CVE-2026-5394
GHSA Identifier GHSA-r2f4-ff2p-xc64
Severity HIGH
CVSS v3.1 Base Score N/A
CWE Classification CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
Affected Product Pimcore/pimcore
Package Ecosystem Packagist
Published Date
Last Updated

How to Fix CVE-2026-5394

To remediate this vulnerability, upgrade all affected Pimcore/pimcore dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

pimcore/pimcore fixed: 12.3.7
Upgrade pimcore/pimcore to 12.3.7
pimcore/pimcore fixed: 11.5.17
Upgrade pimcore/pimcore to 11.5.17
pimcore/pimcore fixed: 2026.1.3
Upgrade pimcore/pimcore to 2026.1.3
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for pimcore/pimcore

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-5394, inspect your project dependencies for Pimcore/pimcore:

inspect dependencies for pimcore/pimcore

Analyze the terminal output to locate any version of Pimcore/pimcore in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 12.3.7), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'), where the product constructs all or part of an sql command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended sql command when it is sent to a downstream component. without sufficient removal or quoting of sql syntax in user-controllable inputs, the generated sql query can cause those inputs to be interpreted as sql instead of ordinary user data. In Pimcore/pimcore, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

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/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: ```http POST /pimcore-studio/api/class/definition/configuration-view/detail/1/import ``` Minimal malicious JSON fragment: ```json { "compositeIndices": [ { "index_key": "poc_idx", "index_type": "query", "index_columns": [ "slider), DROP COLUMN `oo_className` -- " ] } ] } ``` Reproduction: 1. Authenticate as an administrator with permission to manage/import class definitions. 2. Export an existing class definition or prepare a valid class-definition JSON document. 3. Replace only the `compositeIndices` section with the payload above. 4. 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 TABLE` statement 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: ```php $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: <img width="3004" height="1686" alt="Dragons-img" src="https://github.com/user-attachments/assets/2e920636-ce7e-4f8b-b80c-88fb3c4c5299" /> ## Our security policy We have reserved the ID CVE-2026-5394 to refer to this issue from now on. [Disclosure policy](https://fluidattacks.com/advisories/policy) ## 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

CVE-2026-5394 Affected Pimcore/pimcore Versions

3 component(s)
Fixed Versions:
12.3.711.5.172026.1.3
Product / Package Ecosystem Affected Versions Fixed Version
pimcore/pimcore
Packagist
≥ 12.0.0-RC1
< 12.3.7
12.3.7
pimcore/pimcore
Packagist
< 11.5.17
11.5.17
pimcore/pimcore
Packagist
≥ 2026.1.0
< 2026.1.3
2026.1.3

References

Frequently Asked Questions

What is CVE-2026-5394?
CVE-2026-5394 is a security vulnerability in Pimcore/pimcore involving Pimcore Platform - SQL Injection in DataObject composite index handling during class definition import/save under CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection').
Which Pimcore/pimcore versions are affected?
Affected versions include releases prior to 12.3.7, 11.5.17, 2026.1.3 across affected packages: pimcore/pimcore.
What version fixes CVE-2026-5394?
Upgrading to 12.3.7, 11.5.17, 2026.1.3 (or the latest patched release for your respective branch) resolves the vulnerability.
Is pimcore/pimcore affected?
Yes, pimcore/pimcore is affected in releases prior to 12.3.7, 11.5.17, 2026.1.3. Upgrade your dependency to 12.3.7, 11.5.17, 2026.1.3 or later.
What CWE is associated with CVE-2026-5394?
CVE-2026-5394 is classified under CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.).
How can I check Packagist dependencies for CVE-2026-5394?
Run the dependency tree command: 'inspect dependencies for pimcore/pimcore'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-r2f4-ff2p-xc64",
  "modified" : "2026-07-10T19:08:01Z",
  "published" : "2026-05-28T20:47:10Z",
  "aliases" : [ "CVE-2026-5394" ],
  "summary" : "Pimcore Platform - SQL Injection in DataObject composite index handling during class definition import/save",
  "details" : "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.\n\nAs 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.\n\nWe 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.\n\nPlease 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.\n\n## Description\nAn 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.\n\nThe 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.\n\nAlthough 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.\n\n## Vulnerability\n### Root cause\n1. Source:\n   - `Pimcore\\Model\\DataObject\\ClassDefinition\\Service::importClassDefinitionFromJson()` accepts `compositeIndices` directly from imported JSON.\n2. Assignment:\n   - `Pimcore\\Model\\DataObject\\ClassDefinition::setCompositeIndices()` does not enforce an allowlist for index names or column names.\n   - The only special handling is a ManyToOne relation rewrite to `__id` and `__type`, which is not a security control.\n3. Sink:\n   - `Pimcore\\Model\\DataObject\\Traits\\CompositeIndexTrait::updateCompositeIndices()` builds raw SQL with string concatenation and executes it via `$this->db->executeQuery(...)`.\n4. Missing protection:\n   - `quoteIdentifier()` is used for the `SHOW INDEXES` query, but not for the dynamic `ALTER TABLE` statements.\n   - No server-side schema validation restricts `index_key` or `index_columns` to known safe identifier characters.\n\n### Confirmed source-to-sink path\n1. `importClassDefinitionFromJson()` decodes attacker-controlled JSON and forwards `compositeIndices`.\n2. `setCompositeIndices()` stores those values without sanitizing identifier content.\n3. `ClassDefinition::save()` reaches `ClassDefinition\\Dao::update()`.\n4. `Dao::update()` calls `updateCompositeIndices()` for:\n   - `object_store_<classId>`\n   - `object_query_<classId>`\n5. `Localizedfield\\Dao` also calls `updateCompositeIndices()` for:\n   - localized query tables\n   - localized store tables\n\n### Why this is exploitable\nThe vulnerable `ADD INDEX` statement is built as:\n\n```php\n'ALTER TABLE `'.$table.'` ADD INDEX `' . $key.'` ('.$columnName.');'\n```\n\n`$columnName` is produced from `implode(',', $columns)` and is not quoted or validated. A malicious `index_columns` element such as:\n\n```text\nslider), DROP COLUMN `oo_className` -- \n```\n\nproduces SQL of the form:\n\n```sql\nALTER TABLE `object_query_<id>` ADD INDEX `c_poc_idx` (slider), DROP COLUMN `oo_className` -- );\n```\n\nThis 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.\n\n### Impact\nThe 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.\n\nPractical impact includes:\n- unauthorized schema modification on object query/store tables\n- backend denial of service by breaking expected table layout\n- data integrity impact for DataObject storage and queries\n\n`index_key` is also concatenated into SQL without proper identifier escaping, but the most defensible exploitation path is through `index_columns`.\n\nRelevant code:\n- `models/DataObject/ClassDefinition/Service.php:92-137`\n- `models/DataObject/ClassDefinition.php:994-1006`\n- `models/DataObject/Traits/CompositeIndexTrait.php:30-85`\n- `models/DataObject/ClassDefinition/Dao.php:217-218`\n- `models/DataObject/Localizedfield/Dao.php:945-951`\n\n## PoC\n### Application-level PoC\nPreconditions:\n- valid authenticated administrative session\n- ability to import or save a class definition containing `compositeIndices`\n\nThe original report reproduced the issue through an authenticated Studio endpoint:\n\n```http\nPOST /pimcore-studio/api/class/definition/configuration-view/detail/1/import\n```\n\nMinimal malicious JSON fragment:\n\n```json\n{\n  \"compositeIndices\": [\n    {\n      \"index_key\": \"poc_idx\",\n      \"index_type\": \"query\",\n      \"index_columns\": [\n        \"slider), DROP COLUMN `oo_className` -- \"\n      ]\n    }\n  ]\n}\n```\n\nReproduction:\n1. Authenticate as an administrator with permission to manage/import class definitions.\n2. Export an existing class definition or prepare a valid class-definition JSON document.\n3. Replace only the `compositeIndices` section with the payload above.\n4. Import the modified definition or save the class through the administrative workflow.\n\nExpected result:\n- Pimcore reaches `updateCompositeIndices()` during class save/import.\n- The backend executes an attacker-influenced `ALTER TABLE` statement against the target object table.\n- The affected class table is modified unexpectedly, for example by dropping a column or otherwise changing schema.\n\n### Minimal source-level confirmation\nThe behavior is directly visible from the code path:\n\n```php\n$newIndicesMap['c_' . $key] = implode(',', $columns);\n$columnName = $newIndicesMap[$key];\n$this->db->executeQuery(\n    'ALTER TABLE `'.$table.'` ADD INDEX `' . $key.'` ('.$columnName.');'\n);\n```\n\nNo escaping or allowlist validation is applied to `$columns` before they are interpolated into SQL.\n\n## Evidence of Exploitation\n\n- Video of exploitation:\n\nhttps://github.com/user-attachments/assets/64a49147-12a5-4550-ba22-cb4383523557\n\n- Static evidence:\n\n<img width=\"3004\" height=\"1686\" alt=\"Dragons-img\" src=\"https://github.com/user-attachments/assets/2e920636-ce7e-4f8b-b80c-88fb3c4c5299\" />\n\n## Our security policy\nWe have reserved the ID CVE-2026-5394 to refer to this issue from now on.\n\n[Disclosure policy](https://fluidattacks.com/advisories/policy)\n\n## System Information\nPimcore Platform\nVersion `v12.3.3`\nDatabase layer: `doctrine/dbal` `^4.4`\nOperating System: Any\n\n## References\nGithub Repository: https://github.com/pimcore/pimcore\nSecurity: https://github.com/pimcore/pimcore/security",
  "severity" : [ {
    "type" : "CVSS_V4",
    "score" : "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"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "pimcore/pimcore"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "12.0.0-RC1"
      }, {
        "fixed" : "12.3.7"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 12.3.6"
    }
  }, {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "pimcore/pimcore"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "11.5.17"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 11.5.16"
    }
  }, {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "pimcore/pimcore"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2026.1.0"
      }, {
        "fixed" : "2026.1.3"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/pimcore/pimcore/security/advisories/GHSA-r2f4-ff2p-xc64"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-5394"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/pimcore/pimcore/pull/19108"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/pimcore/pimcore/commit/6df625ff74015dc11f4bbe76170ce45bbd5dd61d"
  }, {
    "type" : "WEB",
    "url" : "https://fluidattacks.com/es/advisories/dragons"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/pimcore/pimcore"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/pimcore/pimcore/releases/tag/v12.3.7"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-89" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-05-28T20:47:10Z",
    "nvd_published_at" : null
  }
}