From c420d1d5356f6979b7af3cc46bd182f3ac9edaeb Mon Sep 17 00:00:00 2001 From: Kevin Marsh Date: Mon, 24 Jul 2023 12:27:57 -0700 Subject: [PATCH] django_rawsql_used: support keyword arguments used in `RawSQL` (#765) Fix rule B611: django_rawsql_used breaking when a user passes in keyword arguments to Django's `RawSQL`. Resolves: #764 --- bandit/plugins/django_sql_injection.py | 7 ++++++- examples/django_sql_injection_raw.py | 2 ++ tests/functional/test_functional.py | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/bandit/plugins/django_sql_injection.py b/bandit/plugins/django_sql_injection.py index 4d5df1aaa..a57ff46a3 100644 --- a/bandit/plugins/django_sql_injection.py +++ b/bandit/plugins/django_sql_injection.py @@ -129,7 +129,12 @@ def django_rawsql_used(context): description = "Use of RawSQL potential SQL attack vector." if context.is_module_imported_like("django.db.models"): if context.call_function_name == "RawSQL": - sql = context.node.args[0] + if context.node.args: + sql = context.node.args[0] + else: + kwargs = keywords2dict(context.node.keywords) + sql = kwargs["sql"] + if not isinstance(sql, ast.Str): return bandit.Issue( severity=bandit.MEDIUM, diff --git a/examples/django_sql_injection_raw.py b/examples/django_sql_injection_raw.py index adc7aff47..ee4230273 100644 --- a/examples/django_sql_injection_raw.py +++ b/examples/django_sql_injection_raw.py @@ -9,3 +9,5 @@ raw = '"username") AS "val" FROM "auth_user"' \ ' WHERE "username"="admin" OR 1=%s --' User.objects.annotate(val=RawSQL(raw, [0])) +User.objects.annotate(val=RawSQL(sql='{}secure'.format('no'), params=[])) +User.objects.annotate(val=RawSQL(params=[], sql='{}secure'.format('no'))) diff --git a/tests/functional/test_functional.py b/tests/functional/test_functional.py index aba300e33..7835e7488 100644 --- a/tests/functional/test_functional.py +++ b/tests/functional/test_functional.py @@ -527,8 +527,8 @@ def test_django_sql_injection_raw(self): """Test insecure raw functions on Django.""" expect = { - "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 4, "HIGH": 0}, - "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 4, "HIGH": 0}, + "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 6, "HIGH": 0}, + "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 6, "HIGH": 0}, } self.check_example("django_sql_injection_raw.py", expect)