3
# Copyright 2014 Hewlett-Packard Development Company, L.P.
5
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6
# not use this file except in compliance with the License. You may obtain
7
# a copy of the License at
9
# http://www.apache.org/licenses/LICENSE-2.0
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
# License for the specific language governing permissions and limitations
18
from bandit.core.test_properties import *
19
from bandit.core import utils
22
def _ast_build_string(data):
23
# used to return a string representation of AST data
25
if isinstance(data, ast.Str):
26
# Already a string, just return the value
27
return utils.safe_str(data.s)
29
if isinstance(data, ast.BinOp):
30
# need to build the string from a binary operation
31
return _ast_binop_stringify(data)
33
if isinstance(data, ast.Name):
34
# a variable, stringify the variable name
35
return "[[" + utils.safe_str(data.id) + "]]"
37
return "XXX" # placeholder for unaccounted for values
40
def _ast_binop_stringify(data):
41
# used to recursively build a string from a binary operation
45
return _ast_build_string(left) + _ast_build_string(right)
49
def hardcoded_sql_expressions(context):
50
statement = context.statement['node']
51
if isinstance(statement, ast.Assign):
52
test_str = _ast_build_string(statement.value).lower()
54
elif isinstance(statement, ast.Expr):
56
if isinstance(statement.value, ast.Call):
57
ctx_str = context.string_val.lower()
58
for arg in statement.value.args:
59
temp_str = _ast_build_string(arg).lower()
60
if ctx_str in temp_str:
63
test_str = context.string_val.lower()
66
(test_str.startswith('select ') and ' from ' in test_str) or
67
test_str.startswith('insert into') or
68
(test_str.startswith('update ') and ' set ' in test_str) or
69
test_str.startswith('delete from ')
71
# if sqlalchemy is not imported and it looks like they are using SQL
72
# statements, mark it as a medium severity issue
73
if not context.is_module_imported_like("sqlalchemy"):
75
severity=bandit.MEDIUM,
76
confidence=bandit.LOW,
77
text="Possible SQL injection vector through string-based "
78
"query construction, without SQLAlchemy use."
81
# otherwise, if sqlalchemy is being used, mark it as low severity
85
confidence=bandit.LOW,
86
text="Possible SQL injection vector through string-based "