Skip to content

Commit 4d94bd8

Browse files
committed
Update setup.cfg
Signed-off-by: Eric Brown <[email protected]>
1 parent c4af4a8 commit 4d94bd8

11 files changed

+83
-76
lines changed

bandit/core/blacklisting.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ def blacklist(context, config):
3535
func = context.node.func
3636
if isinstance(func, ast.Name) and func.id == "__import__":
3737
if len(context.node.args):
38-
if isinstance(context.node.args[0], ast.Str):
39-
name = context.node.args[0].s
38+
if isinstance(context.node.args[0], ast.Constant):
39+
name = context.node.args[0].value
4040
else:
4141
# TODO(??): import through a variable, need symbol tab
4242
name = "UNKNOWN"

bandit/core/context.py

+7-15
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,13 @@ def _get_literal_value(self, literal):
178178
:param literal: The AST literal to convert
179179
:return: The value of the AST literal
180180
"""
181-
if isinstance(literal, ast.Num):
182-
literal_value = literal.n
183-
184-
elif isinstance(literal, ast.Str):
185-
literal_value = literal.s
181+
if isinstance(literal, ast.Constant):
182+
if isinstance(literal.value, bool):
183+
literal_value = str(literal.value)
184+
elif literal.value is None:
185+
literal_value = str(literal.value)
186+
else:
187+
literal_value = literal.value
186188

187189
elif isinstance(literal, ast.List):
188190
return_list = list()
@@ -205,19 +207,9 @@ def _get_literal_value(self, literal):
205207
elif isinstance(literal, ast.Dict):
206208
literal_value = dict(zip(literal.keys, literal.values))
207209

208-
elif isinstance(literal, ast.Ellipsis):
209-
# what do we want to do with this?
210-
literal_value = None
211-
212210
elif isinstance(literal, ast.Name):
213211
literal_value = literal.id
214212

215-
elif isinstance(literal, ast.NameConstant):
216-
literal_value = str(literal.value)
217-
218-
elif isinstance(literal, ast.Bytes):
219-
literal_value = literal.s
220-
221213
else:
222214
literal_value = None
223215

bandit/core/node_visitor.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import ast
66
import logging
77
import operator
8+
import sys
89

910
from bandit.core import constants
1011
from bandit.core import tester as b_tester
@@ -168,7 +169,7 @@ def visit_Str(self, node):
168169
:param node: The node that is being inspected
169170
:return: -
170171
"""
171-
self.context["str"] = node.s
172+
self.context["str"] = node.value
172173
if not isinstance(node._bandit_parent, ast.Expr): # docstring
173174
self.context["linerange"] = b_utils.linerange(node._bandit_parent)
174175
self.update_scores(self.tester.run_tests(self.context, "Str"))
@@ -181,7 +182,7 @@ def visit_Bytes(self, node):
181182
:param node: The node that is being inspected
182183
:return: -
183184
"""
184-
self.context["bytes"] = node.s
185+
self.context["bytes"] = node.value
185186
if not isinstance(node._bandit_parent, ast.Expr): # docstring
186187
self.context["linerange"] = b_utils.linerange(node._bandit_parent)
187188
self.update_scores(self.tester.run_tests(self.context, "Bytes"))

bandit/core/utils.py

+18-4
Original file line numberDiff line numberDiff line change
@@ -273,12 +273,12 @@ def linerange(node):
273273
def concat_string(node, stop=None):
274274
"""Builds a string from a ast.BinOp chain.
275275
276-
This will build a string from a series of ast.Str nodes wrapped in
276+
This will build a string from a series of ast.Constant nodes wrapped in
277277
ast.BinOp nodes. Something like "a" + "b" + "c" or "a %s" % val etc.
278278
The provided node can be any participant in the BinOp chain.
279279
280-
:param node: (ast.Str or ast.BinOp) The node to process
281-
:param stop: (ast.Str or ast.BinOp) Optional base node to stop at
280+
:param node: (ast.Constant or ast.BinOp) The node to process
281+
:param stop: (ast.Constant or ast.BinOp) Optional base node to stop at
282282
:returns: (Tuple) the root node of the expression, the string value
283283
"""
284284

@@ -300,7 +300,10 @@ def _get(node, bits, stop=None):
300300
node = node._bandit_parent
301301
if isinstance(node, ast.BinOp):
302302
_get(node, bits, stop)
303-
return (node, " ".join([x.s for x in bits if isinstance(x, ast.Str)]))
303+
return (
304+
node,
305+
" ".join([x.value for x in bits if isinstance(x, ast.Constant)]),
306+
)
304307

305308

306309
def get_called_name(node):
@@ -361,6 +364,17 @@ def parse_ini_file(f_loc):
361364
def check_ast_node(name):
362365
"Check if the given name is that of a valid AST node."
363366
try:
367+
# These ast Node types don't exist in Python 3.14, but plugins may
368+
# still check on them.
369+
if sys.version_info >= (3, 14) and name in (
370+
"Num",
371+
"Str",
372+
"Ellipsis",
373+
"NameConstant",
374+
"Bytes",
375+
):
376+
return name
377+
364378
node = getattr(ast, name)
365379
if issubclass(node, ast.AST):
366380
return name

bandit/plugins/django_sql_injection.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def django_extra_used(context):
6868
if key in kwargs:
6969
if isinstance(kwargs[key], ast.List):
7070
for val in kwargs[key].elts:
71-
if not isinstance(val, ast.Str):
71+
if not isinstance(val, ast.Constant):
7272
insecure = True
7373
break
7474
else:
@@ -77,12 +77,12 @@ def django_extra_used(context):
7777
if not insecure and "select" in kwargs:
7878
if isinstance(kwargs["select"], ast.Dict):
7979
for k in kwargs["select"].keys:
80-
if not isinstance(k, ast.Str):
80+
if not isinstance(k, ast.Constant):
8181
insecure = True
8282
break
8383
if not insecure:
8484
for v in kwargs["select"].values:
85-
if not isinstance(v, ast.Str):
85+
if not isinstance(v, ast.Constant):
8686
insecure = True
8787
break
8888
else:
@@ -135,7 +135,7 @@ def django_rawsql_used(context):
135135
kwargs = keywords2dict(context.node.keywords)
136136
sql = kwargs["sql"]
137137

138-
if not isinstance(sql, ast.Str):
138+
if not isinstance(sql, ast.Constant):
139139
return bandit.Issue(
140140
severity=bandit.MEDIUM,
141141
confidence=bandit.MEDIUM,

bandit/plugins/django_xss.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def evaluate_var(xss_var, parent, until, ignore_nodes=None):
9696
break
9797
to = analyser.is_assigned(node)
9898
if to:
99-
if isinstance(to, ast.Str):
99+
if isinstance(to, ast.Constant):
100100
secure = True
101101
elif isinstance(to, ast.Name):
102102
secure = evaluate_var(to, parent, to.lineno, ignore_nodes)
@@ -105,7 +105,7 @@ def evaluate_var(xss_var, parent, until, ignore_nodes=None):
105105
elif isinstance(to, (list, tuple)):
106106
num_secure = 0
107107
for some_to in to:
108-
if isinstance(some_to, ast.Str):
108+
if isinstance(some_to, ast.Constant):
109109
num_secure += 1
110110
elif isinstance(some_to, ast.Name):
111111
if evaluate_var(
@@ -131,7 +131,10 @@ def evaluate_call(call, parent, ignore_nodes=None):
131131
secure = False
132132
evaluate = False
133133
if isinstance(call, ast.Call) and isinstance(call.func, ast.Attribute):
134-
if isinstance(call.func.value, ast.Str) and call.func.attr == "format":
134+
if (
135+
isinstance(call.func.value, ast.Constant)
136+
and call.func.attr == "format"
137+
):
135138
evaluate = True
136139
if call.keywords:
137140
evaluate = False # TODO(??) get support for this
@@ -140,7 +143,7 @@ def evaluate_call(call, parent, ignore_nodes=None):
140143
args = list(call.args)
141144
num_secure = 0
142145
for arg in args:
143-
if isinstance(arg, ast.Str):
146+
if isinstance(arg, ast.Constant):
144147
num_secure += 1
145148
elif isinstance(arg, ast.Name):
146149
if evaluate_var(arg, parent, call.lineno, ignore_nodes):
@@ -167,7 +170,7 @@ def evaluate_call(call, parent, ignore_nodes=None):
167170
def transform2call(var):
168171
if isinstance(var, ast.BinOp):
169172
is_mod = isinstance(var.op, ast.Mod)
170-
is_left_str = isinstance(var.left, ast.Str)
173+
is_left_str = isinstance(var.left, ast.Constant)
171174
if is_mod and is_left_str:
172175
new_call = ast.Call()
173176
new_call.args = []
@@ -212,7 +215,7 @@ def check_risk(node):
212215
secure = evaluate_call(xss_var, parent)
213216
elif isinstance(xss_var, ast.BinOp):
214217
is_mod = isinstance(xss_var.op, ast.Mod)
215-
is_left_str = isinstance(xss_var.left, ast.Str)
218+
is_left_str = isinstance(xss_var.left, ast.Constant)
216219
if is_mod and is_left_str:
217220
parent = node._bandit_parent
218221
while not isinstance(parent, (ast.Module, ast.FunctionDef)):
@@ -272,5 +275,5 @@ def django_mark_safe(context):
272275
]
273276
if context.call_function_name in affected_functions:
274277
xss = context.node.args[0]
275-
if not isinstance(xss, ast.Str):
278+
if not isinstance(xss, ast.Constant):
276279
return check_risk(context.node)

bandit/plugins/general_hardcoded_password.py

+16-16
Original file line numberDiff line numberDiff line change
@@ -83,45 +83,45 @@ def hardcoded_password_string(context):
8383
# looks for "candidate='some_string'"
8484
for targ in node._bandit_parent.targets:
8585
if isinstance(targ, ast.Name) and RE_CANDIDATES.search(targ.id):
86-
return _report(node.s)
86+
return _report(node.value)
8787
elif isinstance(targ, ast.Attribute) and RE_CANDIDATES.search(
8888
targ.attr
8989
):
90-
return _report(node.s)
90+
return _report(node.value)
9191

9292
elif isinstance(
9393
node._bandit_parent, ast.Subscript
94-
) and RE_CANDIDATES.search(node.s):
94+
) and RE_CANDIDATES.search(node.value):
9595
# Py39+: looks for "dict[candidate]='some_string'"
9696
# subscript -> index -> string
9797
assign = node._bandit_parent._bandit_parent
9898
if isinstance(assign, ast.Assign) and isinstance(
99-
assign.value, ast.Str
99+
assign.value, ast.Constant
100100
):
101-
return _report(assign.value.s)
101+
return _report(assign.value.value)
102102

103103
elif isinstance(node._bandit_parent, ast.Index) and RE_CANDIDATES.search(
104-
node.s
104+
node.value
105105
):
106106
# looks for "dict[candidate]='some_string'"
107107
# assign -> subscript -> index -> string
108108
assign = node._bandit_parent._bandit_parent._bandit_parent
109109
if isinstance(assign, ast.Assign) and isinstance(
110-
assign.value, ast.Str
110+
assign.value, ast.Constant
111111
):
112-
return _report(assign.value.s)
112+
return _report(assign.value.value)
113113

114114
elif isinstance(node._bandit_parent, ast.Compare):
115115
# looks for "candidate == 'some_string'"
116116
comp = node._bandit_parent
117117
if isinstance(comp.left, ast.Name):
118118
if RE_CANDIDATES.search(comp.left.id):
119-
if isinstance(comp.comparators[0], ast.Str):
120-
return _report(comp.comparators[0].s)
119+
if isinstance(comp.comparators[0], ast.Constant):
120+
return _report(comp.comparators[0].value)
121121
elif isinstance(comp.left, ast.Attribute):
122122
if RE_CANDIDATES.search(comp.left.attr):
123-
if isinstance(comp.comparators[0], ast.Str):
124-
return _report(comp.comparators[0].s)
123+
if isinstance(comp.comparators[0], ast.Constant):
124+
return _report(comp.comparators[0].value)
125125

126126

127127
@test.checks("Call")
@@ -176,8 +176,8 @@ def hardcoded_password_funcarg(context):
176176
"""
177177
# looks for "function(candidate='some_string')"
178178
for kw in context.node.keywords:
179-
if isinstance(kw.value, ast.Str) and RE_CANDIDATES.search(kw.arg):
180-
return _report(kw.value.s)
179+
if isinstance(kw.value, ast.Constant) and RE_CANDIDATES.search(kw.arg):
180+
return _report(kw.value.value)
181181

182182

183183
@test.checks("FunctionDef")
@@ -242,5 +242,5 @@ def hardcoded_password_default(context):
242242
# go through all (param, value)s and look for candidates
243243
for key, val in zip(context.node.args.args, defs):
244244
if isinstance(key, (ast.Name, ast.arg)):
245-
if isinstance(val, ast.Str) and RE_CANDIDATES.search(key.arg):
246-
return _report(val.s)
245+
if isinstance(val, ast.Constant) and RE_CANDIDATES.search(key.arg):
246+
return _report(val.value)

bandit/plugins/injection_shell.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616

1717
def _evaluate_shell_call(context):
18-
no_formatting = isinstance(context.node.args[0], ast.Str)
18+
no_formatting = isinstance(context.node.args[0], ast.Constant)
1919

2020
if no_formatting:
2121
return bandit.LOW
@@ -83,16 +83,14 @@ def has_shell(context):
8383
for key in keywords:
8484
if key.arg == "shell":
8585
val = key.value
86-
if isinstance(val, ast.Num):
87-
result = bool(val.n)
86+
if isinstance(val, ast.Constant):
87+
result = bool(val.value)
8888
elif isinstance(val, ast.List):
8989
result = bool(val.elts)
9090
elif isinstance(val, ast.Dict):
9191
result = bool(val.keys)
9292
elif isinstance(val, ast.Name) and val.id in ["False", "None"]:
9393
result = False
94-
elif isinstance(val, ast.NameConstant):
95-
result = val.value
9694
else:
9795
result = True
9896
return result
@@ -687,7 +685,9 @@ def start_process_with_partial_path(context, config):
687685
node = node.elts[0]
688686

689687
# make sure the param is a string literal and not a var name
690-
if isinstance(node, ast.Str) and not full_path_match.match(node.s):
688+
if isinstance(node, ast.Constant) and not full_path_match.match(
689+
node.value
690+
):
691691
return bandit.Issue(
692692
severity=bandit.LOW,
693693
confidence=bandit.HIGH,

bandit/plugins/injection_sql.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def _evaluate_ast(node):
9696
elif isinstance(
9797
node._bandit_parent, ast.Attribute
9898
) and node._bandit_parent.attr in ("format", "replace"):
99-
statement = node.s
99+
statement = node.value
100100
# Hierarchy for "".format() is Wrapper -> Call -> Attribute -> Str
101101
wrapper = node._bandit_parent._bandit_parent._bandit_parent
102102
if node._bandit_parent.attr == "replace":
@@ -107,14 +107,14 @@ def _evaluate_ast(node):
107107
substrings = [
108108
child
109109
for child in node._bandit_parent.values
110-
if isinstance(child, ast.Str)
110+
if isinstance(child, ast.Constant)
111111
]
112112
# JoinedStr consists of list of Constant and FormattedValue
113113
# instances. Let's perform one test for the whole string
114114
# and abandon all parts except the first one to raise one
115115
# failed test instead of many for the same SQL statement.
116116
if substrings and node == substrings[0]:
117-
statement = "".join([str(child.s) for child in substrings])
117+
statement = "".join([str(child.value) for child in substrings])
118118
wrapper = node._bandit_parent._bandit_parent
119119

120120
if isinstance(wrapper, ast.Call): # wrapped in "execute" call?

bandit/plugins/tarfile_unsafe_members.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def is_filter_data(context):
9898
for keyword in context.node.keywords:
9999
if keyword.arg == "filter":
100100
arg = keyword.value
101-
return isinstance(arg, ast.Str) and arg.s == "data"
101+
return isinstance(arg, ast.Constant) and arg.value == "data"
102102

103103

104104
@test.test_id("B202")

0 commit comments

Comments
 (0)