Skip to content

Commit c379b96

Browse files
committed
fix: resolve all high-severity bandit security findings
Address all 18 high-severity issues identified by bandit static security analysis (B324, B602, B605, B202). Each finding has been individually evaluated for the test framework context. B324 (hashlib weak hash): Add usedforsecurity=False to SHA1/MD5 calls used for non-security purposes (job IDs, variant fingerprints, lock filenames, test assertions). B602/B605 (shell execution): Suppress with nosec justification as subprocess and shell usage is core to Avocado's test framework functionality. B202 (tarfile extractall): Suppress with nosec justification as the tarfile filter= parameter requires Python 3.12+ but Avocado supports Python 3.9+. Reference: #5270 Assisted-by: Claude (Anthropic) ~95% Signed-off-by: Christopher Lusk <clusk@redhat.com>
1 parent 8fa8228 commit c379b96

File tree

12 files changed

+46
-20
lines changed

12 files changed

+46
-20
lines changed

avocado/core/job_id.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,9 @@ def create_unique_job_id():
2626
:return: 40 digit hex number string
2727
:rtype: str
2828
"""
29-
return hashlib.sha1(hex(_RAND_POOL.getrandbits(160)).encode()).hexdigest()
29+
return (
30+
hashlib.sha1( # nosec B324 -- not used for security, generates unique job IDs
31+
hex(_RAND_POOL.getrandbits(160)).encode(),
32+
usedforsecurity=False,
33+
).hexdigest()
34+
)

avocado/core/output.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,9 @@ def __init__(self):
636636
except utils_path.CmdNotFoundError as details:
637637
raise RuntimeError(f"Unable to enable pagination: {details}")
638638

639-
self.pipe = os.popen(paginator, "w")
639+
self.pipe = os.popen(
640+
paginator, "w"
641+
) # nosec B605 -- paginator command is user-configured or safe default (less)
640642

641643
def __del__(self):
642644
self.close()

avocado/core/varianter.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ def get_variant_name(variant):
7373
return (
7474
get_variant_name(variant)
7575
+ "-"
76-
+ hashlib.sha1(fingerprint.encode(astring.ENCODING)).hexdigest()[:4]
76+
+ hashlib.sha1( # nosec B324 -- not used for security, generates variant IDs
77+
fingerprint.encode(astring.ENCODING),
78+
usedforsecurity=False,
79+
).hexdigest()[:4]
7780
)
7881

7982

avocado/utils/archive.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,9 @@ def extract(self, path="."):
362362
)
363363

364364
# Handle regular archives (zip and tar)
365-
self._engine.extractall(path)
365+
self._engine.extractall(
366+
path
367+
) # nosec B202 -- archive extraction is intentional; filter= requires Python 3.12+
366368
if self.is_zip:
367369
self._update_zip_extra_attrs(path)
368370
files = self._engine.namelist()

avocado/utils/network/interfaces.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,10 +1031,10 @@ def ping_flood(int_name, peer_ip, ping_count):
10311031
returns False on ping flood failure.
10321032
:rtype: bool
10331033
"""
1034-
cmd = f"ping -I {int_name} {peer_ip} -c {ping_count} -f "
1034+
cmd = ["ping", "-I", int_name, peer_ip, "-c", str(ping_count), "-f"]
10351035
with subprocess.Popen(
10361036
cmd,
1037-
shell=True,
1037+
shell=False,
10381038
stdout=subprocess.PIPE,
10391039
stderr=subprocess.STDOUT,
10401040
universal_newlines=True,

avocado/utils/partition.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ class MtabLock:
5252
def __init__(self, timeout=60):
5353
self.timeout = timeout
5454
self.mtab = None
55-
device_hash = hashlib.sha1(self.device.encode("utf-8")).hexdigest()
55+
device_hash = hashlib.sha1( # nosec B324 -- not used for security, generates lock filename
56+
self.device.encode("utf-8"),
57+
usedforsecurity=False,
58+
).hexdigest()
5659
lock_filename = os.path.join(tempfile.gettempdir(), device_hash)
5760
self.lock = filelock.FileLock(lock_filename, timeout=self.timeout)
5861

avocado/utils/process.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ def signal_handler(*args):
780780
else:
781781
cmd = self.cmd
782782
try:
783-
self._popen = subprocess.Popen( # pylint: disable=R1732
783+
self._popen = subprocess.Popen( # nosec B602 -- shell execution is core to this test framework # pylint: disable=R1732
784784
cmd,
785785
stdout=subprocess.PIPE,
786786
stderr=subprocess.PIPE,

avocado/utils/software_manager/backends/dpkg.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ def extract_from_package(package_path, dest_path=None):
9090
data_tarball_name = archive.list()[2]
9191
member_data = archive.read_member(data_tarball_name)
9292
with tarfile.open(fileobj=io.BytesIO(member_data)) as tarball:
93-
tarball.extractall(dest)
93+
tarball.extractall(
94+
dest
95+
) # nosec B202 -- extracting deb package data; filter= requires Python 3.12+
9496
return dest
9597

9698
def list_files(self, package):

examples/tests/sleeptenmin.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ def test(self):
2828
if method == "builtin":
2929
time.sleep(length)
3030
elif method == "shell":
31-
os.system(f"sleep {length}")
31+
os.system(
32+
f"sleep {length}"
33+
) # nosec B605 -- example test, length is an integer from test params

optional_plugins/varianter_pict/avocado_varianter_pict/varianter_pict.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,14 @@ def __iter__(self):
185185
for variant in self.variants:
186186
base_id = "-".join([variant.get(key) for key in self.headers])
187187
variant_ids.append(
188-
base_id + "-" + hashlib.sha1(base_id.encode()).hexdigest()[:4]
188+
base_id
189+
+ "-"
190+
+ hashlib.sha1( # nosec B324 -- not used for security, generates variant IDs
191+
base_id.encode(),
192+
usedforsecurity=False,
193+
).hexdigest()[
194+
:4
195+
]
189196
)
190197

191198
for vid, variant in zip(variant_ids, self.variants):

0 commit comments

Comments
 (0)