Product Details
- Product: Django
- Component: ORM (QuerySet, FilteredRelation), GIS (PostGIS RasterField)
- Attack Class: SQL Injection
- Attack Vector: Remote (HTTP request → ORM misuse)
- Authentication Required: No (if vulnerable code path is exposed)
- Impact Scope: Database integrity, data exfiltration, potential RCE via DB extensions
- Affected Deployments: Applications dynamically building ORM queries using user-controlled input
CVE Summary Table
| CVE Name | CVE ID | CVSS Score | Severity | Exploitability | Exploit Availability | Affected Area |
|---|---|---|---|---|---|---|
| Django QuerySet.order_by() SQL Injection | CVE-2026-1312 | Not Assigned | High (Projected) | High | No public PoC | ORM / QuerySet |
| Django FilteredRelation Alias Injection | CVE-2026-1287 | Not Assigned | High (Projected) | Medium–High | No public PoC | ORM / FilteredRelation |
| Django PostGIS RasterField Injection | CVE-2026-1207 | Not Assigned | Critical (Projected) | Medium | No public PoC | GIS / PostGIS |
Why “Projected”? These ratings are based on historical Django SQLi issues and exploitation feasibility, not vendor scoring.
CVE-2026-1312
Django QuerySet.order_by() SQL Injection via crafted column aliases in FilteredRelation
What’s Going On
Django allows developers to sort query results using QuerySet.order_by(). When FilteredRelation is used, Django internally builds SQL column aliases dynamically.
If untrusted input reaches order_by() and is combined with FilteredRelation aliases, Django fails to fully sanitize the alias name before embedding it into the SQL ORDER BY clause.
This opens the door to SQL injection through alias manipulation, not values — which makes it harder to spot in code reviews.
How This Could Be Exploited
An attacker supplies a crafted parameter that ends up controlling the alias name:
- Injects SQL keywords via alias
- Breaks out of
ORDER BY - Appends subqueries or function calls
This is especially dangerous because:
- ORMs are often trusted implicitly
- Developers assume
order_by()is safe - WAFs often ignore ORDER BY clauses
Example Payload Pattern (Conceptual)
?sort=alias_name) DESC, (SELECT pg_sleep(5))--
Impact
- Blind SQL injection
- Data extraction
- Database DoS
- Potential RCE if dangerous extensions exist
MITRE ATT&CK Mapping
- T1190 – Exploit Public-Facing Application
- T1059.007 – Command Execution via SQL
- T1046 – Data Discovery
CVE-2026-1287
Django FilteredRelation SQL Injection via control characters in column aliases
What’s Going On
This issue is more subtle.
Django does not properly normalize or reject control characters (newline, tab, carriage return, Unicode separators) inside column aliases used by FilteredRelation.
Certain databases (PostgreSQL especially) will:
- Accept these characters
- Reinterpret query structure
- Allow logical SQL injection without obvious syntax breaks
How This Could Be Exploited
Attackers inject non-printable characters that:
- Bypass blacklist-based filters
- Alter query parsing
- Create stealth SQL payloads invisible in logs
Example Payload Pattern
alias_name%0aFROM%20users--
Why This Is Dangerous
- Payloads don’t look malicious in logs
- Copy-paste inspections miss control characters
- SIEM rules often ignore them
Impact
- Stealth data exfiltration
- Authentication bypass queries
- Silent corruption of ORM logic
MITRE ATT&CK Mapping
- T1036 – Masquerading
- T1190 – Exploit Public-Facing Application
- T1027 – Obfuscated Files or Information
CVE-2026-1207
Django PostGIS RasterField SQL Injection via band index parameter
What’s Going On
Django’s RasterField supports band indexing for PostGIS raster operations.
The band index is expected to be numeric, but in certain ORM paths it is:
- Passed as a raw SQL fragment
- Not strictly cast or validated
- Embedded into GIS SQL functions
This allows non-numeric injection into raster queries.
How This Could Be Exploited
An attacker supplies a crafted band index value:
band=1); SELECT version();--
Because PostGIS raster functions are executed at the database level, this becomes a direct SQL injection path.
Why This Is Critical
- GIS endpoints are often exposed publicly
- Raster queries run with high DB privileges
- PostGIS supports advanced file and system interactions
Impact
- Full database compromise
- Lateral movement via DB extensions
- Data destruction or ransom-style attacks
MITRE ATT&CK Mapping
- T1190 – Exploit Public-Facing Application
- T1105 – Ingress Tool Transfer
- T1485 – Data Destruction
Detection Guidance
What to Look For
Log Sources
- Django application logs
- Database query logs (PostgreSQL)
- Web access logs
- ORM debug logs (if enabled)
Suspicious Indicators
- ORDER BY clauses with parentheses
- Unexpected SQL keywords in aliases
- Control characters in query logs
- Raster queries with non-numeric band values
- Time-delay patterns (
pg_sleep,benchmark)
Detection Rules
SQL Injection via ORDER BY
ORDER\s+BY.*(\(|;|--|/\*)
Control Character Detection
[\x00-\x1F\x7F]
RasterField Abuse
ST_Band.*[^0-9]
Exploit Availability
- Public PoC: No
- In-the-wild exploitation: Unknown
- Weaponization likelihood: High (once disclosed)
Official Patch Status
- Vendor Advisory: Not published
- Official Patch: Not released
- Mitigation Until Patch:
- Never pass user input directly to
order_by() - Enforce strict allowlists for sorting fields
- Validate
FilteredRelationalias names - Cast RasterField band indices explicitly to integers
- Disable ORM debug logging in production
- Never pass user input directly to
Final Takeaway
These vulnerabilities break a long-standing assumption:
“ORMs protect you from SQL injection.”
They don’t — if advanced features are misused.
If confirmed and disclosed, these CVEs would represent high-impact ORM-level injection flaws that bypass traditional security controls and deserve immediate remediation.
