# DJG101 This check looks for ways that Django SQL Injection protection is being bypassed, by using quoted parameters. The check looks at the following use cases: * Use of `RawSQL()` constructor directly * Use of `cursor.execute()` * Use of `raw()` on a `Manager` instance Whilst the methods support parametrized queries, if the `%s` value is quoted with single-quotes, the value is still vulnerable to SQL injection. This also applies to parametrized arguments, where it includes a substitute reference, e.g. `'%(variable)s'`. ## Example The first example is using the RawSQL constructor directly and annotating a query set: ```python from django.db.models.expressions import RawSQL qs.annotate(val=RawSQL("select col from sometable where othercol = '%s'", (someparam,))) # this is bad! ``` Another example is using the `raw()` method on a manager to filter results, exposing SQL injection: ```python from django import things from .models import User def my_view(self): User.objects.raw("SELECT * FROM myapp_person WHERE last_name = '%s'", [lname]) # this is also bad! ``` Cursors can also be exploited using the same technique: ```python from django.db import connection def my_custom_sql(self): with connection.cursor() as cursor: cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz]) cursor.execute("SELECT foo FROM bar WHERE baz = '%s'", [self.baz]) row = cursor.fetchone() return row ``` ## Fixes Remove the quotations from the string values: ```python ("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz]) # good ("UPDATE bar SET foo = 1 WHERE baz = '%s'", [self.baz]) # bad! ``` ## See Also * [Official Documentation](https://docs.djangoproject.com/en/3.0/ref/models/expressions/#django.db.models.expressions.RawSQL)