diff --git a/avocado/core/job_id.py b/avocado/core/job_id.py index 95c9962df2..097aca101e 100644 --- a/avocado/core/job_id.py +++ b/avocado/core/job_id.py @@ -26,4 +26,9 @@ def create_unique_job_id(): :return: 40 digit hex number string :rtype: str """ - return hashlib.sha1(hex(_RAND_POOL.getrandbits(160)).encode()).hexdigest() + return ( + hashlib.sha1( # nosec B324 -- not used for security, generates unique job IDs + hex(_RAND_POOL.getrandbits(160)).encode(), + usedforsecurity=False, + ).hexdigest() + ) diff --git a/avocado/core/output.py b/avocado/core/output.py index 9254e2166d..a167ed0392 100644 --- a/avocado/core/output.py +++ b/avocado/core/output.py @@ -636,7 +636,9 @@ def __init__(self): except utils_path.CmdNotFoundError as details: raise RuntimeError(f"Unable to enable pagination: {details}") - self.pipe = os.popen(paginator, "w") + self.pipe = os.popen( + paginator, "w" + ) # nosec B605 -- paginator command is user-configured or safe default (less) def __del__(self): self.close() diff --git a/avocado/core/varianter.py b/avocado/core/varianter.py index 9800cd8448..eaa096dbbe 100644 --- a/avocado/core/varianter.py +++ b/avocado/core/varianter.py @@ -73,7 +73,10 @@ def get_variant_name(variant): return ( get_variant_name(variant) + "-" - + hashlib.sha1(fingerprint.encode(astring.ENCODING)).hexdigest()[:4] + + hashlib.sha1( # nosec B324 -- not used for security, generates variant IDs + fingerprint.encode(astring.ENCODING), + usedforsecurity=False, + ).hexdigest()[:4] ) diff --git a/avocado/utils/archive.py b/avocado/utils/archive.py index b41a7ebba4..8a624364c1 100644 --- a/avocado/utils/archive.py +++ b/avocado/utils/archive.py @@ -362,7 +362,9 @@ def extract(self, path="."): ) # Handle regular archives (zip and tar) - self._engine.extractall(path) + self._engine.extractall( + path + ) # nosec B202 -- archive extraction is intentional; filter= requires Python 3.12+ if self.is_zip: self._update_zip_extra_attrs(path) files = self._engine.namelist() diff --git a/avocado/utils/network/interfaces.py b/avocado/utils/network/interfaces.py index 40bc072d17..1e55290abe 100644 --- a/avocado/utils/network/interfaces.py +++ b/avocado/utils/network/interfaces.py @@ -1031,10 +1031,10 @@ def ping_flood(int_name, peer_ip, ping_count): returns False on ping flood failure. :rtype: bool """ - cmd = f"ping -I {int_name} {peer_ip} -c {ping_count} -f " + cmd = ["ping", "-I", int_name, peer_ip, "-c", str(ping_count), "-f"] with subprocess.Popen( cmd, - shell=True, + shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, diff --git a/avocado/utils/partition.py b/avocado/utils/partition.py index 7ef96421af..267c5fad67 100644 --- a/avocado/utils/partition.py +++ b/avocado/utils/partition.py @@ -52,7 +52,10 @@ class MtabLock: def __init__(self, timeout=60): self.timeout = timeout self.mtab = None - device_hash = hashlib.sha1(self.device.encode("utf-8")).hexdigest() + device_hash = hashlib.sha1( # nosec B324 -- not used for security, generates lock filename + self.device.encode("utf-8"), + usedforsecurity=False, + ).hexdigest() lock_filename = os.path.join(tempfile.gettempdir(), device_hash) self.lock = filelock.FileLock(lock_filename, timeout=self.timeout) diff --git a/avocado/utils/process.py b/avocado/utils/process.py index 663c2989a1..4427a6fff2 100644 --- a/avocado/utils/process.py +++ b/avocado/utils/process.py @@ -780,7 +780,7 @@ def signal_handler(*args): else: cmd = self.cmd try: - self._popen = subprocess.Popen( # pylint: disable=R1732 + self._popen = subprocess.Popen( # nosec B602 -- shell execution is core to this test framework # pylint: disable=R1732 cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, diff --git a/avocado/utils/software_manager/backends/dpkg.py b/avocado/utils/software_manager/backends/dpkg.py index dc30885284..ff1be6d09e 100644 --- a/avocado/utils/software_manager/backends/dpkg.py +++ b/avocado/utils/software_manager/backends/dpkg.py @@ -90,7 +90,9 @@ def extract_from_package(package_path, dest_path=None): data_tarball_name = archive.list()[2] member_data = archive.read_member(data_tarball_name) with tarfile.open(fileobj=io.BytesIO(member_data)) as tarball: - tarball.extractall(dest) + tarball.extractall( + dest + ) # nosec B202 -- extracting deb package data; filter= requires Python 3.12+ return dest def list_files(self, package): diff --git a/examples/tests/sleeptenmin.py b/examples/tests/sleeptenmin.py index 397d3e1b66..c08d09fb9f 100644 --- a/examples/tests/sleeptenmin.py +++ b/examples/tests/sleeptenmin.py @@ -28,4 +28,6 @@ def test(self): if method == "builtin": time.sleep(length) elif method == "shell": - os.system(f"sleep {length}") + os.system( + f"sleep {length}" + ) # nosec B605 -- example test, length is an integer from test params diff --git a/optional_plugins/varianter_pict/avocado_varianter_pict/varianter_pict.py b/optional_plugins/varianter_pict/avocado_varianter_pict/varianter_pict.py index 95d24c59a7..1298684e1f 100644 --- a/optional_plugins/varianter_pict/avocado_varianter_pict/varianter_pict.py +++ b/optional_plugins/varianter_pict/avocado_varianter_pict/varianter_pict.py @@ -185,7 +185,14 @@ def __iter__(self): for variant in self.variants: base_id = "-".join([variant.get(key) for key in self.headers]) variant_ids.append( - base_id + "-" + hashlib.sha1(base_id.encode()).hexdigest()[:4] + base_id + + "-" + + hashlib.sha1( # nosec B324 -- not used for security, generates variant IDs + base_id.encode(), + usedforsecurity=False, + ).hexdigest()[ + :4 + ] ) for vid, variant in zip(variant_ids, self.variants): diff --git a/selftests/functional/list.py b/selftests/functional/list.py index 4baac979c8..688860a53e 100644 --- a/selftests/functional/list.py +++ b/selftests/functional/list.py @@ -124,11 +124,11 @@ def _run_with_timeout(self, cmd_line, timeout): deadline = current_time + timeout # pylint: disable=W1509 test_process = subprocess.Popen( - cmd_line, + process.cmd_split(cmd_line), stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setsid, - shell=True, + shell=False, ) while not test_process.poll(): if time.monotonic() > deadline: diff --git a/selftests/unit/utils/crypto.py b/selftests/unit/utils/crypto.py index 71ae4d0302..1f666dba86 100644 --- a/selftests/unit/utils/crypto.py +++ b/selftests/unit/utils/crypto.py @@ -21,7 +21,7 @@ def test_hash_file_md5_default(self): """Test MD5 hash calculation with default algorithm.""" content = b"Hello, World!" filepath = self._create_test_file(content) - expected = hashlib.md5(content).hexdigest() + expected = hashlib.md5(content, usedforsecurity=False).hexdigest() result = crypto.hash_file(filepath) self.assertEqual(result, expected) @@ -39,7 +39,7 @@ def test_hash_file_with_size_limit(self): content = b"ABCDEFGHIJ" # 10 bytes filepath = self._create_test_file(content) # Hash only first 5 bytes - tests size < file_size path - expected = hashlib.md5(b"ABCDE").hexdigest() + expected = hashlib.md5(b"ABCDE", usedforsecurity=False).hexdigest() result = crypto.hash_file(filepath, size=5) self.assertEqual(result, expected) @@ -47,7 +47,7 @@ def test_hash_file_size_larger_than_file(self): """Test that size larger than file hashes the whole file.""" content = b"Small file" filepath = self._create_test_file(content) - expected = hashlib.md5(content).hexdigest() + expected = hashlib.md5(content, usedforsecurity=False).hexdigest() # Request more bytes than file contains - tests size > file_size branch result = crypto.hash_file(filepath, size=1000000) self.assertEqual(result, expected) @@ -56,7 +56,7 @@ def test_hash_file_size_falsy_hashes_whole_file(self): """Test that falsy size values (None, 0) hash the entire file.""" content = b"Complete file content" filepath = self._create_test_file(content) - expected = hashlib.md5(content).hexdigest() + expected = hashlib.md5(content, usedforsecurity=False).hexdigest() # Both None and 0 are falsy - tests 'not size' branch self.assertEqual(crypto.hash_file(filepath, size=None), expected) self.assertEqual(crypto.hash_file(filepath, size=0), expected) @@ -65,7 +65,7 @@ def test_hash_file_size_falsy_hashes_whole_file(self): def test_hash_file_empty_file(self): """Test hashing an empty file.""" filepath = self._create_test_file(b"") - expected = hashlib.md5(b"").hexdigest() + expected = hashlib.md5(b"", usedforsecurity=False).hexdigest() result = crypto.hash_file(filepath) self.assertEqual(result, expected) @@ -73,7 +73,7 @@ def test_hash_file_binary_content(self): """Test hashing a file with all possible byte values.""" content = bytes(range(256)) # All byte values 0-255 filepath = self._create_test_file(content) - expected = hashlib.md5(content).hexdigest() + expected = hashlib.md5(content, usedforsecurity=False).hexdigest() result = crypto.hash_file(filepath) self.assertEqual(result, expected) @@ -82,7 +82,7 @@ def test_hash_file_larger_than_chunk_size(self): # Create content larger than io.DEFAULT_BUFFER_SIZE (typically 8192) content = b"x" * 100000 filepath = self._create_test_file(content) - expected = hashlib.md5(content).hexdigest() + expected = hashlib.md5(content, usedforsecurity=False).hexdigest() result = crypto.hash_file(filepath) self.assertEqual(result, expected)