Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-26198-analysis — Deep dive into a critical SQL injection in Python's Ormar ORM — reproduction, fix, and tests | Kitploit
Tools/GitHubGitHub/sergicortesabadia/cve-2026-26198-analysis
Vulnerability AnalysisCode AnalysisWeb SecurityPapers & ResearchLearning & Education
GitHubsergicortesabadia/cve-2026-26198-analysis

CVE-2026-26198-analysis

Deep dive into a critical SQL injection in Python's Ormar ORM — reproduction, fix, and tests

View Repository
5 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-26198 — SQL Injection in Ormar ORM

A deep dive into a critical (CVSS 9.8) SQL injection vulnerability in a Python async ORM, with reproduction, analysis, and fix.

The Vulnerability

Ormar is a popular async mini ORM for Python, commonly used with FastAPI and Starlette. Versions 0.9.9 through 0.22.0 contain a SQL injection vulnerability in the min() and max() aggregate methods.

The root cause is a "partial implementation" bug: while sum() and avg() validate that the column parameter refers to an actual numeric field, min() and max() skip this check entirely and pass user input straight into sqlalchemy.text() — a raw SQL sink.

An attacker can inject a subquery as the "column" parameter:

root@kitploit:~
# Expected usage
await Item.objects.max("price")  # → SELECT max(price) FROM items

# Attack payload
await Item.objects.max("(SELECT password FROM users LIMIT 1)")
# → SELECT max((SELECT password FROM users LIMIT 1)) FROM items
# Returns the admin's password!

Quick Facts

AttributeValue
CVE IDCVE-2026-26198
CVSS Score9.8 (Critical)
CWECWE-89: SQL Injection
Affectedormar 0.9.9 – 0.22.0
Fixed inormar 0.23.0
PublishedFebruary 24, 2026
Auth needed?None — unauthenticated

Project Structure

root@kitploit:~
├── README.md               ← You are here
├── vulnerable_app.py       ← Minimal FastAPI app with the vulnerable pattern
├── exploit_demo.py         ← Safe PoC showing the injection in action
├── patched_app.py          ← The fixed version with input validation
├── test_vulnerability.py   ← Tests proving the vuln exists and the fix works
├── requirements.txt
└── analysis/
    └── root_cause.md       ← Detailed code-level analysis of the bug

Running the Demo

root@kitploit:~
git clone https://github.com/YOUR_USERNAME/CVE-2026-26198-analysis.git
cd CVE-2026-26198-analysis
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt

# Run the tests (no external DB needed — uses SQLite)
python -m pytest test_vulnerability.py -v

# Run the interactive exploit demo
python exploit_demo.py

The Fix

The fix validates that the column parameter matches an actual field on the model before it reaches sqlalchemy.text(). This is done through a whitelist approach: only column names that exist in the model's field definitions are allowed.

See patched_app.py for the implementation and analysis/root_cause.md for the full breakdown.

Key Takeaways

  1. ORMs are not automatic SQL injection protection. If an ORM method accepts a raw string and passes it to a text clause, it's just as dangerous as writing raw SQL.
  2. Partial validation is worse than no validation. The fact that sum()/avg() were validated but min()/max() were not created a false sense of security.
  3. Whitelist, don't blacklist. The fix validates against known-good column names rather than trying to filter malicious patterns.

References

  • GitHub Advisory (GHSA-xxh2-68g9-8jqr)
  • NVD Entry
  • Ormar Repository

License

MIT

Download Tool