Skip to content

Commit 95d6300

Browse files
authored
Merge branch 'main' into pre-commit-ci-update-config
2 parents 862ed22 + c8c8a55 commit 95d6300

9 files changed

Lines changed: 67 additions & 34 deletions

File tree

.github/workflows/build-publish-image.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
3535

3636
- name: Log in to GitHub Container Registry
37-
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3
37+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
3838
with:
3939
registry: ghcr.io
4040
username: ${{ github.actor }}
@@ -51,7 +51,7 @@ jobs:
5151
5252
- name: Build and push Docker image
5353
id: build-and-push
54-
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
54+
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
5555
with:
5656
context: .
5757
file: ./docker/Dockerfile

bandit/cli/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ def _log_option_source(default_val, arg_val, ini_val, option_name):
9494
return ini_val
9595
else:
9696
return None
97-
# No value passed to commad line and default value is used
97+
# No value passed to command line and default value is used
9898
elif default_val == arg_val:
9999
return ini_val if ini_val else arg_val
100-
# Certainly a value is passed to commad line
100+
# Certainly a value is passed to command line
101101
else:
102102
return arg_val
103103

bandit/core/manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def discover_files(self, targets, recursive=False, excluded_paths=""):
204204
:param recursive: True/False - whether to add all files from dirs
205205
:return:
206206
"""
207-
# We'll mantain a list of files which are added, and ones which have
207+
# We'll maintain a list of files which are added, and ones which have
208208
# been explicitly excluded
209209
files_list = set()
210210
excluded_files = set()

bandit/core/tester.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ def run_tests(self, raw_context, checktype):
112112
):
113113
LOG.warning(
114114
f"nosec encountered ({test._test_id}), but no "
115-
f"failed test on line {temp_context['lineno']}"
115+
f"failed test on file "
116+
f"{temp_context['filename']}:"
117+
f"{temp_context['lineno']}"
116118
)
117119

118120
except Exception as e:

bandit/core/utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,9 @@ def parse_ini_file(f_loc):
370370
def check_ast_node(name):
371371
"Check if the given name is that of a valid AST node."
372372
try:
373-
# These ast Node types don't exist in Python 3.14, but plugins may
374-
# still check on them.
375-
if sys.version_info >= (3, 14) and name in (
373+
# These ast Node types were deprecated in Python 3.12 and removed
374+
# in Python 3.14, but plugins may still check on them.
375+
if sys.version_info >= (3, 12) and name in (
376376
"Num",
377377
"Str",
378378
"Ellipsis",

bandit/plugins/huggingface_unsafe_download.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
6161
"""
6262

63+
import ast
6364
import string
6465

6566
import bandit
@@ -114,7 +115,19 @@ def huggingface_unsafe_download(context):
114115
if not any(module in qualname_parts for module in required_modules):
115116
return
116117

117-
# Check for revision parameter (the key security control)
118+
# Check for revision parameter (the key security control).
119+
# First, check the raw AST to see if a revision/commit_id keyword was
120+
# passed as a non-literal expression (variable, attribute, subscript,
121+
# function call, etc.). In those cases we cannot statically determine
122+
# the value, so we give the user the benefit of the doubt.
123+
call_node = context._context.get("call")
124+
if call_node is not None:
125+
for kw in getattr(call_node, "keywords", []):
126+
if kw.arg in ("revision", "commit_id") and not isinstance(
127+
kw.value, ast.Constant
128+
):
129+
return
130+
118131
revision_value = context.get_call_arg_value("revision")
119132
commit_id_value = context.get_call_arg_value("commit_id")
120133

bandit/plugins/injection_shell.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from bandit.core import test_properties as test
1111

1212
# yuck, regex: starts with a windows drive letter (eg C:)
13-
# or one of our path delimeter characters (/, \, .)
13+
# or one of our path delimiter characters (/, \, .)
1414
full_path_match = re.compile(r"^(?:[A-Za-z](?=\:)|[\\\/\.])")
1515

1616

bandit/plugins/trojansource.py

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,29 @@
5454
@test.test_id("B613")
5555
@test.checks("File")
5656
def trojansource(context):
57-
with open(context.filename, "rb") as src_file:
58-
encoding, _ = detect_encoding(src_file.readline)
59-
with open(context.filename, encoding=encoding) as src_file:
60-
for lineno, line in enumerate(src_file.readlines(), start=1):
61-
for char in BIDI_CHARACTERS:
62-
try:
63-
col_offset = line.index(char) + 1
64-
except ValueError:
65-
continue
66-
text = (
67-
"A Python source file contains bidirectional"
68-
" control characters (%r)." % char
69-
)
70-
b_issue = bandit.Issue(
71-
severity=bandit.HIGH,
72-
confidence=bandit.MEDIUM,
73-
cwe=issue.Cwe.INAPPROPRIATE_ENCODING_FOR_OUTPUT_CONTEXT,
74-
text=text,
75-
lineno=lineno,
76-
col_offset=col_offset,
77-
)
78-
b_issue.linerange = [lineno]
79-
return b_issue
57+
src_data = context.file_data
58+
src_data.seek(0)
59+
encoding, _ = detect_encoding(src_data.readline)
60+
src_data.seek(0)
61+
for lineno, line in enumerate(
62+
src_data.read().decode(encoding).splitlines(), start=1
63+
):
64+
for char in BIDI_CHARACTERS:
65+
try:
66+
col_offset = line.index(char) + 1
67+
except ValueError:
68+
continue
69+
text = (
70+
"A Python source file contains bidirectional"
71+
" control characters (%r)." % char
72+
)
73+
b_issue = bandit.Issue(
74+
severity=bandit.HIGH,
75+
confidence=bandit.MEDIUM,
76+
cwe=issue.Cwe.INAPPROPRIATE_ENCODING_FOR_OUTPUT_CONTEXT,
77+
text=text,
78+
lineno=lineno,
79+
col_offset=col_offset,
80+
)
81+
b_issue.linerange = [lineno]
82+
return b_issue

examples/huggingface_unsafe_download.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,18 @@
147147
repo_id="org/model_name",
148148
revision="5d0f2e8a7f1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d"
149149
)
150+
151+
152+
# Example #24: Revision passed as a variable (can't be statically checked)
153+
MODEL_REVISION = "548fc3543a"
154+
safe_model_variable = AutoModel.from_pretrained(
155+
"org/model_name",
156+
revision=MODEL_REVISION
157+
)
158+
159+
# Example #25: Revision from a dict/subscript access
160+
config = {"revision": "abc1234567"}
161+
safe_model_subscript = AutoModel.from_pretrained(
162+
"org/model_name",
163+
revision=config["revision"]
164+
)

0 commit comments

Comments
 (0)