Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

github логотип

GHSA-h4ph-crvj-9h92

Опубликовано: 27 мая 2026
Источник: github
Github: Прошло ревью
CVSS3: 8.8

Описание

Pimcore Admin Classic Bundle Vulnerable to SQL Injection in Translation Grid Date Filter via Unsanitized Property Parameter

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.

Severity

CVSS 3.1: 8.8 (High) — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

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.

Пакеты

Наименование

pimcore/admin-ui-classic-bundle

composer
Затронутые версииВерсия исправления

>= 2.0.0-RC1, <= 2.3.5

2.3.6

Наименование

pimcore/admin-ui-classic-bundle

composer
Затронутые версииВерсия исправления

< 1.7.18

1.7.18

EPSS

Процентиль: 28%
0.0035
Низкий

8.8 High

CVSS3

Дефекты

CWE-89

Связанные уязвимости

CVSS3: 8.8
nvd
1 день назад

Pimcore's Admin Classic Bundle provides a Backend UI for Pimcore. Versions prior to 2.3.6 and 1.7.18 have a SQL injection vulnerability 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. Versiosn 2.3.6 and 1.7.18 fix the issue.

CVSS3: 8.8
debian
1 день назад

Pimcore's Admin Classic Bundle provides a Backend UI for Pimcore. Vers ...

EPSS

Процентиль: 28%
0.0035
Низкий

8.8 High

CVSS3

Дефекты

CWE-89