CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-CH7P-MPV4-4VG4
4.90.01%

Shopping for Shells: Inside the CoreShop SQL Injection

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 24, 2026·6 min read·5 visits

PoC Available

Executive Summary (TL;DR)

CoreShop versions prior to 4.1.8 contain a Blind SQL Injection vulnerability in the Admin Reports interface. User input (e.g., store IDs, limits) is directly concatenated into raw SQL queries. Authenticated admins can exploit this to extract sensitive database information. Fixed in version 4.1.8 by implementing proper parameter binding and integer casting.

A classic Blind SQL Injection vulnerability was discovered in the administrative reporting modules of CoreShop, a popular e-commerce framework for Pimcore. Despite the availability of modern ORM features, developers resorted to manual string concatenation for SQL queries, allowing authenticated administrators to inject arbitrary SQL commands. This flaw permits data exfiltration via boolean or time-based techniques, effectively turning the reporting dashboard into a database dumping tool.

The Hook: Reports Are Boring (Until They Leaks Data)

CoreShop is the heavy lifter for e-commerce on the Pimcore platform. It handles the carts, the money, and the customers. Naturally, it comes with a suite of administrative reports to tell you how many people abandoned their carts or which payment provider is making you the most money. These reports are usually the driest part of the application—grids of numbers meant for managers.

But under the hood, these reports were constructed with a recklessness that harkens back to the PHP tutorials of 2005. While the rest of the application likely leverages the safety of Symfony's Doctrine ORM, the reporting module decided to go 'off-roading' with raw SQL. The result? A direct pipeline from a URL parameter to the database engine.

This vulnerability is a perfect example of the 'secure framework fallacy'—the belief that using a modern, secure framework like Symfony automatically protects you. It doesn't help if you deliberately bypass its safety features to concatenate strings like a cowboy.

The Flaw: Manual Concatenation in a Modern World

The root cause here is technically simple but conceptually frustrating. The vulnerability exists within src/CoreShop/Bundle/CoreBundle/Report/, affecting nearly every report class from AbandonedCartsReport.php to VouchersReport.php. The application accepts parameters from the request—things like store, offset, limit, and orderState—and passes them into a function that builds a SQL query string.

Instead of using parameterized queries (prepared statements) for every variable, the code mixed and matched. It used ? placeholders for dates, but for the store ID or the LIMIT clause, it just dropped the variable right into the string. It looked something like this:

$sqlQuery = "SELECT ... WHERE cart.store = $storeId ... LIMIT $offset,$limit";

This is the coding equivalent of locking your front door (using authentication) but leaving the window wide open. Because the $storeId variable wasn't sanitized or typed, an attacker could append SQL logic. Since the interface doesn't dump stack traces to the screen (blind), you can't just UNION SELECT your way to glory immediately—you have to ask the database Yes/No questions or tell it to go to sleep.

The Code: The Smoking Gun

Let's look at the diff, because nothing explains bad code like seeing it fixed. The vulnerability lived in how the _sql string was constructed in the getData method of the report classes.

Before (Vulnerable): The code directly interpolated variables. Note the $store and $limit variables sitting naked in the query string.

$sql = 'SELECT ' . $query . ' 
        FROM ' . $this->getTableName() . ' cart 
        WHERE cart.store = ' . $params['store'] . ' 
        LIMIT ' . $params['offset'] . ',' . $params['limit'];
 
$stmt = $this->connection->executeQuery($sql);

After (Fixed): The patch introduces named placeholders (:store) and enforces strict type casting for syntax elements that are hard to parameterize, like LIMIT and OFFSET.

$sql = 'SELECT ' . $query . ' 
        FROM ' . $this->getTableName() . ' cart 
        WHERE cart.store = :store 
        LIMIT ' . (int)$params['offset'] . ',' . (int)$params['limit'];
 
$stmt = $this->connection->executeQuery($sql, ['store' => $params['store']]);

> [!NOTE] > The patch also includes a clever fix for IN clauses (arrays), dynamically generating placeholders like :id0, :id1 instead of imploding the array into the string. This closes the door on array-based injection vectors as well.

The Exploit: Asking the Database Twenty Questions

So, you are an authenticated administrator. Maybe you are a low-level admin with access to reports but not user management, and you want to escalate. Or maybe you've hijacked a session. You browse to the 'Abandoned Carts' report. The URL looks like this:

https://admin.target.com/admin/reports/abandoned-carts?store=1

The exploit involves modifying that store parameter. Since we are in a Blind SQLi scenario, we can't see the output of our injection, but we can infer it.

Scenario 1: Boolean Blind We inject a condition that is true, then one that is false, and watch if the report returns data.

  • Payload A (True): ?store=1 AND 1=1 -> Report loads normally.
  • Payload B (False): ?store=1 AND 1=0 -> Report is empty.

If the server behaves differently, we can script this to extract data bit by bit.

Scenario 2: Time-Based If the report always returns empty or behaves strangely, we use time. We tell the database to sleep if our guess is correct.

  • Payload: ?store=1 AND SLEEP(5)

If the report takes 5+ seconds to load, we know we have execution. We can then ask: "Is the first letter of the admin password 'A'? If yes, sleep for 5 seconds."

The Impact: Why Panic?

The CVSS score is a modest 4.9, mostly because it requires High Privileges (PR:H). But don't let that fool you. In the context of e-commerce, 'High Privilege' accounts are often shared or less protected than root infrastructure accounts.

Successful exploitation allows an attacker to dump the entire database. This includes:

  1. Customer PII: Names, addresses, emails, phone numbers.
  2. Order History: Who bought what and when.
  3. Admin Credentials: Password hashes for other administrators (allowing lateral movement).
  4. Configuration Secrets: If stored in the DB, potentially API keys for payment gateways (Stripe, PayPal).

While the attacker cannot modify data (assuming the DB user is read-only for reports, which is a best practice often ignored), the confidentiality loss is total. In a GDPR/CCPA world, this is a nightmare scenario.

The Fix: Parameterize or Perish

The remediation is straightforward: Upgrade to CoreShop 4.1.8. The patch replaces the concatenation with Doctrine's parameter binding mechanisms.

If you cannot upgrade immediately, you are in a tight spot because this logic is baked into the core classes. You could try to mitigate this via a Web Application Firewall (WAF) by blocking common SQL keywords (UNION, SELECT, SLEEP, BENCHMARK) in query parameters, specifically for the /admin/reports path. However, WAFs are bypassable. The only real fix is code that doesn't treat user input like a trusted friend.

Key Takeaway for Developers: Never, ever trust ParameterBag values inside a raw SQL string. Even if you think "It's just an integer," cast it explicitly (int)$val. Better yet, use the Query Builder or Prepared Statements for everything. No exceptions.

Official Patches

CoreShopOfficial patch commit on GitHub
GitHub AdvisoryGitHub Security Advisory GHSA-ch7p-mpv4-4vg4

Fix Analysis (1)

Technical Appendix

CVSS Score
4.9/ 10
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N
EPSS Probability
0.01%
Top 98% most exploited

Affected Systems

CoreShop < 4.1.8

Affected Versions Detail

Product
Affected Versions
Fixed Version
CoreShop
CoreShop
< 4.1.84.1.8
AttributeDetail
CWE IDCWE-89 (SQL Injection)
CVSS v3.14.9 (Medium)
Attack VectorNetwork (Authenticated)
Privileges RequiredHigh (Admin)
ImpactHigh Confidentiality Loss
EPSS Score0.00012
Exploit StatusPoC Available

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059.006Command and Scripting Interpreter: Python
Execution
T1562Impair Defenses
Defense Evasion
CWE-89
SQL Injection

Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

Vulnerability Timeline

Patch Commit Merged
2026-01-07
Advisory Published (GHSA-ch7p-mpv4-4vg4)
2026-01-08
CVE Assigned
2026-01-08
CISA Weekly Summary
2026-01-14

References & Sources

  • [1]CoreShop Security Advisory
  • [2]NVD CVE Detail
Related Vulnerabilities
CVE-2026-22242

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.