Formatting strings used as SQL queries is security-sensitive. It has led in the past to the following vulnerabilities:
SQL queries often need to use a hardcoded SQL string with a dynamic parameter coming from a user request. Formatting a string to add those parameters to the request is a bad practice as it can result in an SQL injection. The safe way to add parameters to a SQL query is to use SQL binding mechanisms.
Note that this rule does not detect SQL injections.
This rule flags the execution of formatted SQL via Django APIs. The goal is to guide security code reviews and to prevent a common bad practice.
A string is considered formatted if it uses one of the following operations:
str.format(...) str % str str + str f"SELECT * FROM mytable WHERE name = '{value}'" F"SELECT * FROM mytable WHERE name = '{value}'" You may be at risk if you answered yes to this question.
You can also reduce the impact of an attack by using a database account with low privileges.
from django.db import models
from django.db import connection
from django.db import connections
from django.db.models.expressions import RawSQL
value = input()
class MyUser(models.Model):
name = models.CharField(max_length=200)
def query_my_user(request, params, value):
MyUser.objects.raw(request + value) # Sensitive
# Parametrized queries
MyUser.objects.raw(request + value, params) # Sensitive.
with connection.cursor() as cursor:
cursor.execute(request + value) # Sensitive
with connections['my_db'].cursor() as cursor:
cursor.execute(request + value) # Sensitive
# https://docs.djangoproject.com/en/2.1/ref/models/expressions/#raw-sql-expressions
RawSQL("select col from %s where mycol = %s and othercol = " + value, ("test",)) # Sensitive
# https://docs.djangoproject.com/en/2.1/ref/models/querysets/#extra
MyUser.objects.extra(
select={
'mycol': "select col from sometable here mycol = %s and othercol = " + value}, # Sensitive
... select_params=(someparam,),
},
)
The current implementation does not follow variables. It will only detect SQL queries which are formatted directly in the function call.