PHP
CVE-2026-44741
HIGH
Severity by source
AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Primary rating from GitHub Advisory · only source for this CVE.
CVSS VectorGitHub Advisory
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Lifecycle Timeline
2DescriptionGitHub Advisory
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 - injectionThe 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.
AnalysisAI
Here is the multi-source synthesis for CVE-2026-44741:
{
"product_name": "Pimcore",
"summary": "SQL injection in Pimcore's admin-ui-classic-bundle (versions <= 2.3.5) allows an authenticated user holding only the translations-view permission to read arbitrary database contents by injecting into the translation grid's date filter. The user-controlled 'property' field of the filter JSON is interpolated directly into a UNIX_TIMESTAMP(DATE(FROM_UNIXTIME(...))) expression at the POST /admin/translation/translations endpoint, behind only a trivially bypassable str_replace('--','') filter. A working proof-of-concept and publicly available exploit code exist; the reporter notes it can be chained with an unsafe-unserialize flaw (GM-249) to reach remote code execution. No EPSS score or CISA KEV listing was supplied.",
"technical_context": "Pimcore is a PHP-based open-source data and experience management platform (DXP/CMS); the affected code lives in its Admin Classic Bundle (Composer package pimcore/admin-ui-classic-bundle, CPE pkg:composer/pimcore_admin-ui-classic-bundle), specifically src/Controller/Admin/TranslationController.php. The translation grid endpoint accepts a JSON 'filter' array; when a filter element has type 'date', the controller reads $filter['property'] (line 565), strips literal '--' sequences (line 569), prefixes the table name (line 577), and embeds the result into the raw SQL string UNIX_TIMESTAMP(DATE(FROM_UNIXTIME({$fieldname}))) (line 593) with no parameter binding, identifier quoting, or column allowlist. This is a textbook CWE-89 (SQL Injection) caused by building a query from untrusted input; the blacklist sanitization fails because comment-style payloads such as /**/ or ---- survive the str_replace, and the value is concatenated unquoted in non-language mode.",
"risk_assessment": "The CVSS 3.1 base score is 8.8 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H): network-reachable, low attack complexity, no user interaction, and only low privileges required, with high impact to confidentiality, integrity and availability. The PR:L requirement is consistent with the description, which states an authenticated account with translations-view permission is needed — so this is not an unauthenticated internet-wide bug, which tempers the raw 8.8. Working exploit code exists (PoC in the advisory), raising real-world likelihood, but there is no CISA KEV entry and no EPSS score was provided, so there is no evidence of active mass exploitation and that probability must be treated as unknown rather than low. The realistic priority is high for any deployment that grants admin/translation panel access to semi-trusted or numerous users (the SQLi can be chained to deserialization and RCE), and moderate where admin access is tightly restricted to fully trusted operators.",
"affected_products": "The affected product is the Pimcore Admin Classic Bundle, Composer package pimcore/admin-ui-classic-bundle (CPE pkg:composer/pimcore_admin-ui-classic-bundle), all versions up to and including 2.3.5, with the vulnerable code in src/Controller/Admin/TranslationController.php exposed via POST /admin/translation/translations. The issue is fixed in version 2.3.6. Details are published in the vendor GitHub Security Advisory GHSA-h4ph-crvj-9h92 (https://github.com/pimcore/pimcore/security/advisories/GHSA-h4ph-crvj-9h92), mirrored at https://github.com/advisories/GHSA-h4ph-crvj-9h92.",
"remediation": "Vendor-released patch: 2.3.6 — upgrade pimcore/admin-ui-classic-bundle to 2.3.6 or later (e.g. composer require pimcore/admin-ui-classic-bundle:^2.3.6), as delivered in release https://github.com/pimcore/admin-ui-classic-bundle/releases/tag/v2.3.6 via PR https://github.com/pimcore/admin-ui-classic-bundle/pull/1111 and commit 80e57a23d9e19574eddfe9b08e8f26785b2b0d90; the fix adds a column allowlist and uses $db->quoteIdentifier() instead of raw interpolation, and also hardens an unserialize call with allowed_classes=false. If immediate patching is not possible, the most effective compensating control is to restrict who holds the translations (translations-view) permission, revoking it from all but fully trusted operators since exploitation requires an authenticated session with that grant; you may also block or tightly access-control the /admin/translation/translations endpoint at a reverse proxy or WAF (trade-off: this breaks legitimate use of the translation grid for affected users) and enable database query logging to alert on anomalous UNION or error-based patterns. Consult advisory GHSA-h4ph-crvj-9h92 for authoritative guidance.",
"exploit_scenario": "An attacker who has obtained any low-privileged Pimcore admin account with translations-view rights logs in and submits a filter such as filter=[{\"property\":\"1))) UNION SELECT password FROM users WHERE ((1\",\"type\":\"date\",\"operator\":\"eq\",\"value\":\"2026-01-01\"}] to the translation grid endpoint, extracting password hashes and other data via UNION/error-based injection. A public proof-of-concept demonstrates exactly this request, and the reporter notes the SQLi can be chained with an unsafe unserialize (GM-249) to escalate to remote code execution; the low attack complexity (AC:L) and network vector (AV:N) make the request straightforward to send once authenticated.",
"exploitation_conditions": "Requires an authenticated Pimcore session whose user holds the translations (translations-view) permission (CVSS PR:L), and the attacker must submit a translation grid filter with type set to 'date' using the 'eq' operator so execution reaches the UNIX_TIMESTAMP(DATE(FROM_UNIXTIME(...))) code path in non-language mode at POST /admin/translation/translations. The injected payload must avoid a literal '--' sequence, trivially satisfied using /**/ or ---- since str_replace removes only the exact '--' string. Limiting factors: exploitation is gated by that authenticated permission (not anonymous), so realistic risk concentrates where admin/translation access is broadly granted; no user interaction is needed (UI:N) and no special OS/platform is required because the flaw is in the PHP application logic itself.",
"attack_chain": "Authenticate with translations-view permission → POST crafted date-filter JSON to /admin/translation/translations → Bypass '--' filter, inject into UNIX_TIMESTAMP expression → Execute UNION/error-based SQL query → Exfiltrate credentials and database data → Chain to unsafe unserialize for RCE",
"confidence_notes": "Affected (<= 2.3.5) and fixed (2.3.6) versions are confirmed by vendor advisory GHSA-h4ph-crvj-9h92, PR #1111, and commit 80e57a23; CWE-89, the CVSS 8.8 vector, and a working PoC are confirmed in the report. The SQLi-to-RCE chain via GM-249 is claimed by the reporter but not independently verified here. No EPSS score and no CISA KEV status were provided, so active-exploitation likelihood is unknown; note also that the supplied PR diff excerpt shows mainly the Dashboard.php unserialize hardening rather than the TranslationController.php SQL fix, so confirm the SQLi remediation against the full 2.3.6 changeset."
}sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not
(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear
ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C
Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au
Util/PHP/eval-stdin.php in PHPUnit before 4.8.28 and 5.x before 5.6.3 allows remote attackers to execute arbitrary PHP c
Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
The get_referers function in /opt/ws/bin/sblistpack in Sophos Web Appliance before 3.7.9.1 and 3.8 before 3.8.1.1 allows
The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1
NetAlertX (formerly PiAlert) versions 23.01.14 through 24.x before 24.10.12 allow unauthenticated command injection thro
The GiveWP - Donation Plugin and Fundraising Platform plugin for WordPress is vulnerable to PHP Object Injection in all
Same weakness CWE-89 – SQL Injection
View allSame technique Deserialization
View allShare
External POC / Exploit Code
Leaving vuln.today
GHSA-h4ph-crvj-9h92