Audit required: Potential SQL injection on `extra` functionBAN-B610
Use of extra in Django querysets should be audited, since unsanitized strings can open up security vulnerabilities. It makes application vulnerable to [SQL injection](SQL injection) attacks.
Sometimes, the Django query syntax by itself can’t easily express a complex WHERE clause. For these edge cases, Django provides the extra() QuerySet modifier — a hook for injecting specific clauses into the SQL generated by a QuerySet.
An SQL injection attack consists of insertion or “injection” of a SQL query via the input data given to an application. It is a very common attack vector.
One should be very careful whenever you use extra(). Use it only if you cannot express your query using other queryset methods.
Bad practice
qs.extra(
... select={'val': "select col from sometable where othercol = %s"},
... select_params=(someparam,),
)
Executing above code snippet is equivalent to the following raw SQL with unsatized input:
qs.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))
References:
- extra() QuerySet modifier in Django
- SQL injection protection in Django
- OWASP Top 10 2021 Category A03 - Injection
- SANS Top 25
- CWE 20 - Improper Input Validation