CVE-2026-26198

9.8 CRITICAL

📋 TL;DR

CVE-2026-26198 is a critical SQL injection vulnerability in Ormar ORM for Python that allows attackers to execute arbitrary SQL queries. Unauthorized users can exploit this to read entire database contents, including tables unrelated to the queried model. All applications using Ormar versions 0.9.9 through 0.22.0 with aggregate queries are affected.

💻 Affected Systems

Products:
  • Ormar ORM for Python
Versions: 0.9.9 through 0.22.0
Operating Systems: All operating systems running Python
Default Config Vulnerable: ⚠️ Yes
Notes: Only affects applications using min() or max() aggregate methods with user-supplied column parameters. Applications using only sum() and avg() are partially protected by numeric type checks.

📦 What is this software?

⚠️ Risk & Real-World Impact

🔴

Worst Case

Complete database compromise including data exfiltration, data modification, and potential privilege escalation through SQL injection.

🟠

Likely Case

Unauthorized data access and exfiltration from any database table accessible to the application's database user.

🟢

If Mitigated

Limited impact with proper input validation and database user privilege restrictions.

🌐 Internet-Facing: HIGH - Web applications using Ormar with user-controlled input in aggregate queries are directly exploitable.
🏢 Internal Only: HIGH - Internal applications remain vulnerable to authenticated users or attackers who gain internal access.

🎯 Exploit Status

Public PoC: ✅ No
Weaponized: LIKELY
Unauthenticated Exploit: ⚠️ Yes
Complexity: LOW

The vulnerability is straightforward to exploit as it requires only passing a malicious string to min() or max() methods. No authentication bypass needed if the vulnerable endpoint is exposed.

🛠️ Fix & Mitigation

✅ Official Fix

Patch Version: 0.23.0

Vendor Advisory: https://github.com/collerek/ormar/security/advisories/GHSA-xxh2-68g9-8jqr

Restart Required: No

Instructions:

1. Update Ormar to version 0.23.0 or later using pip: pip install ormar>=0.23.0
2. Verify no breaking changes in your application
3. Test aggregate queries with min() and max() methods
4. Deploy updated application

🔧 Temporary Workarounds

Input Validation Wrapper

all

Implement custom validation for column parameters before passing to min() and max() methods

# Python code to validate column names
import re

def safe_column_name(column):
    if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', column):
        raise ValueError('Invalid column name')
    return column

Database User Privilege Restriction

all

Limit database user permissions to read-only access on specific tables

-- SQL example for PostgreSQL
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM app_user;
GRANT SELECT ON specific_table TO app_user;

🧯 If You Can't Patch

  • Disable or restrict endpoints using min() and max() aggregate methods with user input
  • Implement web application firewall (WAF) rules to detect and block SQL injection patterns in query parameters

🔍 How to Verify

Check if Vulnerable:

Check if your code uses ormar.QuerySet.min() or ormar.QuerySet.max() with user-supplied parameters. Review requirements.txt or pyproject.toml for ormar version.

Check Version:

python -c "import ormar; print(ormar.__version__)"

Verify Fix Applied:

After updating to 0.23.0+, test that malicious column names (e.g., "(SELECT * FROM users)") are rejected or properly escaped.

📡 Detection & Monitoring

Log Indicators:

  • Unusual SQL queries in database logs with subqueries in aggregate functions
  • Multiple failed login attempts followed by aggregate query attempts
  • Database queries accessing tables not referenced in application code

Network Indicators:

  • Unusually large database response sizes from aggregate query endpoints
  • Rapid sequential requests to aggregate endpoints with varying parameters

SIEM Query:

source="application.logs" AND ("ormar.QuerySet.min" OR "ormar.QuerySet.max") AND ("SELECT" OR "UNION" OR "FROM" NOT IN expected_columns)

🔗 References

📤 Share & Export