PT-2026-43629 · Packagist · Pimcore Admin Classic Bundle
Published
2026-05-27
·
Updated
2026-05-27
·
CVE-2026-44741
CVSS v3.1
8.8
High
| Vector | AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
GitHub Security Advisory Draft — GM-369
Summary
SQL injection in Pimcore's translation grid date filter — the user-supplied
property field from the filter JSON is interpolated directly into a UNIX TIMESTAMP(DATE(FROM UNIXTIME(...))) SQL expression without parameterization or allowlist validation.Affected Component
- Package:
pimcore/admin-ui-classic-bundle - File:
src/Controller/Admin/TranslationController.php - Lines: 565 (input), 569 (inadequate sanitization), 593 (injection point)
- Endpoint:
POST /admin/translation/translations
Description
The translation grid endpoint processes JSON filter parameters. When a filter has
type: "date", the property field is extracted and used to construct a SQL expression:$fieldname = $filter[$propertyField]; // Line 565 — user input
$fieldname = str replace('--', '', $fieldname); // Line 569 — trivially bypassable
$fieldname = $tableName . '.' . $fieldname; // Line 577
$fieldname = "UNIX TIMESTAMP(DATE(FROM UNIXTIME({$fieldname})))"; // Line 593 — injection
The
str replace('--', '') sanitization is trivially bypassable (use /**/ comments or ----). In non-language mode, $fieldname is concatenated directly into the SQL condition without quoting or parameterization.Impact
Authenticated user with translations view permission can extract arbitrary database data via UNION-based or error-based SQL injection. Combined with GM-249 (unsafe unserialize), this enables an SQLi → deserialization → RCE chain.
Proof of Concept
POST /admin/translation/translations
filter=[{"property":"1))) UNION SELECT password FROM users WHERE ((1","type":"date","operator":"eq","value":"2026-01-01"}]
Suggested Fix
Validate
$fieldname against an allowlist of valid column names before SQL interpolation:$allowedDateColumns = ['creationDate', 'modificationDate'];
if (!in array($fieldname, $allowedDateColumns, true)) {
continue;
}
References
- CWE-89: SQL Injection
- Related: CVE-2026-27461 (RLIKE injection in Dependency/Dao.php — different code path)
Suggested Fix
In
TranslationController.php: (1) Add allowlist check for non-language fieldnames before processing. (2) Replace raw string interpolation UNIX TIMESTAMP(DATE(FROM UNIXTIME({$fieldname}))) with $db->quoteIdentifier($fieldname) to prevent SQL injection in date filter expressions.--- a/src/Controller/Admin/TranslationController.php
+++ b/src/Controller/Admin/TranslationController.php
@@ -569,7 +569,15 @@ class TranslationController extends AdminAbstractController
$fieldname = str replace('--', '', $fieldname);
if (!$languageMode && in array($fieldname, $validLanguages)
|| $languageMode && !in array($fieldname, $validLanguages)) {
continue;
}
+ // Allowlist non-language fieldnames to prevent SQL injection
+ $allowedNonLanguageFields = ['key', 'type', 'creationDate', 'modificationDate'];
+ if (!$languageMode && !in array($fieldname, $allowedNonLanguageFields) && !in array($fieldname, $validLanguages)) {
+ continue;
+ }
+
if (!$languageMode) {
$fieldname = $tableName . '.' . $fieldname;
}
@@ -582,7 +590,7 @@ class TranslationController extends AdminAbstractController
} elseif ($filter[$operatorField] == 'eq') {
$operator = '=';
- $fieldname = "UNIX TIMESTAMP(DATE(FROM UNIXTIME({$fieldname})))";
+ // Use validated fieldname only — never interpolate raw user input into SQL functions
+ $fieldname = sprintf('UNIX TIMESTAMP(DATE(FROM UNIXTIME(%s)))', $db->quoteIdentifier($fieldname));
}
Proposed Fix
--- a/src/Controller/Admin/TranslationController.php
+++ b/src/Controller/Admin/TranslationController.php
@@ -569,7 +569,15 @@ class TranslationController extends AdminAbstractController
$fieldname = str replace('--', '', $fieldname);
if (!$languageMode && in array($fieldname, $validLanguages)
|| $languageMode && !in array($fieldname, $validLanguages)) {
continue;
}
+ // Allowlist non-language fieldnames to prevent SQL injection
+ $allowedNonLanguageFields = ['key', 'type', 'creationDate', 'modificationDate'];
+ if (!$languageMode && !in array($fieldname, $allowedNonLanguageFields) && !in array($fieldname, $validLanguages)) {
+ continue;
+ }
+
if (!$languageMode) {
$fieldname = $tableName . '.' . $fieldname;
}
@@ -582,7 +590,7 @@ class TranslationController extends AdminAbstractController
} elseif ($filter[$operatorField] == 'eq') {
$operator = '=';
- $fieldname = "UNIX TIMESTAMP(DATE(FROM UNIXTIME({$fieldname})))";
+ // Use validated fieldname only — never interpolate raw user input into SQL functions
+ $fieldname = sprintf('UNIX TIMESTAMP(DATE(FROM UNIXTIME(%s)))', $db->quoteIdentifier($fieldname));
}
Happy to submit this as a PR against a private fork if that is the preferred workflow.
Fix
SQL injection
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Pimcore Admin Classic Bundle