Skip to content

Commit

Permalink
Detect misuse of psycopg2.sql.SQL composable
Browse files Browse the repository at this point in the history
Add a plugin test to detect when something other than a string
literal is passed to the constructor of the `psycopg2.sql.SQL`
composable object.

Resolves: PyCQA#412
  • Loading branch information
wtkm11 committed May 1, 2020
1 parent 89548b9 commit ae770bb
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ Usage::
B609 linux_commands_wildcard_injection
B610 django_extra_used
B611 django_rawsql_used
B612 psycopg2_sql_injection
B701 jinja2_autoescape_false
B702 use_of_mako_templates
B703 django_mark_safe
Expand Down
40 changes: 40 additions & 0 deletions bandit/plugins/psycopg2_sql_injection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- coding:utf-8 -*-
#
# SPDX-License-Identifier: Apache-2.0

import ast

import bandit
from bandit.core import test_properties as test


@test.checks('Call')
@test.test_id('B612')
def psycopg2_sql_injection(context):
"""**B612: Potential SQL injection on psycopg2 raw SQL composable object **
The `psycopg2.sql.SQL` composable object should not be used to represent
variable identifiers or values that may be controlled by an attacker since
the argument that is passed to the `SQL` constructor is not escaped when
the SQL statement is composed. Instead, `SQL` should only be used to
represent constant strings.
.. seealso::
- https://www.psycopg.org/docs/sql.html
.. versionadded:: 1.5.0
"""
if context.is_module_imported_like('psycopg2.sql'):
if context.call_function_name == 'SQL':
argument = context.node.args[0]
if not isinstance(argument, ast.Str):
return bandit.Issue(
severity=bandit.MEDIUM,
confidence=bandit.MEDIUM,
text=(
"Possible SQL injection vector through instantiation "
"of psycopg2.sql.SQL composable object on an argument "
"other than a string literal."
)
)
4 changes: 4 additions & 0 deletions examples/psycopg2_sql_injection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from psycopg2 import sql

table = 'users; drop table users; --'
sql.SQL('select * from {}').format(sql.SQL(table))
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ bandit.plugins =
# bandit/plugins/ssh_no_host_key_verification.py
ssh_no_host_key_verification = bandit.plugins.ssh_no_host_key_verification:ssh_no_host_key_verification

# bandit/plugins/psycopg2_sql_injection.py
psycopg2_sql_injection = bandit.plugins.psycopg2_sql_injection:psycopg2_sql_injection

[build_sphinx]
all_files = 1
build-dir = doc/build
Expand Down

0 comments on commit ae770bb

Please sign in to comment.