Skip to content

Commit ba593f1

Browse files
1 parent b9150b6 commit ba593f1

2 files changed

Lines changed: 85 additions & 6 deletions

File tree

advisories/github-reviewed/2026/04/GHSA-c8g3-x47w-8q7p/GHSA-c8g3-x47w-8q7p.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-c8g3-x47w-8q7p",
4-
"modified": "2026-05-06T18:32:15Z",
4+
"modified": "2026-05-28T20:47:01Z",
55
"published": "2026-04-27T21:31:02Z",
6-
"aliases": [
7-
"CVE-2026-5394"
8-
],
9-
"summary": "Pimcore admin users can trigger SQL Injection",
10-
"details": "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.\n\nThis issue affects pimcore: 12.3.3.",
6+
"withdrawn": "2026-05-28T20:47:01Z",
7+
"aliases": [],
8+
"summary": "Duplicate Advisory: Pimcore admin users can trigger SQL Injection",
9+
"details": "### Duplicate Advisory\nThis advisory has been withdrawn because it is a duplicate of GHSA-r2f4-ff2p-xc64. This link is maintained to preserve external references.\n\n### Original 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\nThis issue affects pimcore: 12.3.3.",
1110
"severity": [
1211
{
1312
"type": "CVSS_V4",
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-r2f4-ff2p-xc64",
4+
"modified": "2026-05-28T20:47:10Z",
5+
"published": "2026-05-28T20:47:10Z",
6+
"aliases": [
7+
"CVE-2026-5394"
8+
],
9+
"summary": "Pimcore Platform - SQL Injection in DataObject composite index handling during class definition import/save",
10+
"details": "## 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\n## System Information\nPimcore Platform\nVersion `v12.3.3`\nDatabase layer: `doctrine/dbal` `^4.4`\nOperating System: Any\n\n## Resources\nGithub Repository: https://github.com/pimcore/pimcore\nSecurity: https://github.com/pimcore/pimcore/security\n\nThis issue was discovered by Oscar Uribe, Security Researcher at Fluid Attacks, who reached out to Pimcore.\n\nAs part of standard disclosure measures, Fluid Attacks follows a timeline (outlined at https://fluidattacks.com/advisories/policy) that is aligned with ISO/IEC 29147:2018 and ISO/IEC 30111:2019. In short, the timeline works as follows: Fluid Attacks requests acknowledgment of the report within a few days of project maintainers first accessing it, and from there, Fluid Attacks is glad to coordinate a joint disclosure date with the affected party, typically within 90 days of the initial discovery. This allows the maintainers' team reasonable time to assess, develop, and release a fix.\n\n\nThe CVE ID **\"CVE-2026-5394\"** has been reserved for this issue, and the advisory will eventually be published at [https://fluidattacks.com/advisories/dragons](https://fluidattacks.com/advisories/dragons).",
11+
"severity": [
12+
{
13+
"type": "CVSS_V4",
14+
"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"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Packagist",
21+
"name": "pimcore/pimcore"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "12.3.7"
32+
}
33+
]
34+
}
35+
],
36+
"database_specific": {
37+
"last_known_affected_version_range": "<= 12.3.6"
38+
}
39+
}
40+
],
41+
"references": [
42+
{
43+
"type": "WEB",
44+
"url": "https://github.com/pimcore/pimcore/security/advisories/GHSA-r2f4-ff2p-xc64"
45+
},
46+
{
47+
"type": "ADVISORY",
48+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-5394"
49+
},
50+
{
51+
"type": "WEB",
52+
"url": "https://github.com/pimcore/pimcore/pull/19108"
53+
},
54+
{
55+
"type": "WEB",
56+
"url": "https://github.com/pimcore/pimcore/commit/6df625ff74015dc11f4bbe76170ce45bbd5dd61d"
57+
},
58+
{
59+
"type": "WEB",
60+
"url": "https://fluidattacks.com/es/advisories/dragons"
61+
},
62+
{
63+
"type": "PACKAGE",
64+
"url": "https://github.com/pimcore/pimcore"
65+
},
66+
{
67+
"type": "WEB",
68+
"url": "https://github.com/pimcore/pimcore/releases/tag/v12.3.7"
69+
}
70+
],
71+
"database_specific": {
72+
"cwe_ids": [
73+
"CWE-89"
74+
],
75+
"severity": "HIGH",
76+
"github_reviewed": true,
77+
"github_reviewed_at": "2026-05-28T20:47:10Z",
78+
"nvd_published_at": null
79+
}
80+
}

0 commit comments

Comments
 (0)