From c8d5f77b35ffac67a04cf94d8279c6b5c833c667 Mon Sep 17 00:00:00 2001 From: Etienne Schalk <45271239+etienneschalk@users.noreply.github.com> Date: Wed, 28 Feb 2024 00:15:42 +0100 Subject: [PATCH] filter data is safe for tarfile extractall (#1111) * filter data is safe for tarfile extractall * add versionchanged to the docstring --- bandit/plugins/tarfile_unsafe_members.py | 12 ++++++++++++ examples/tarfile_extractall.py | 14 ++++++++++++++ tests/functional/test_functional.py | 4 ++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/bandit/plugins/tarfile_unsafe_members.py b/bandit/plugins/tarfile_unsafe_members.py index 32c1e6127..5ad145c1a 100644 --- a/bandit/plugins/tarfile_unsafe_members.py +++ b/bandit/plugins/tarfile_unsafe_members.py @@ -42,6 +42,9 @@ .. versionadded:: 1.7.5 +.. versionchanged:: 1.7.8 + Added check for filter parameter + """ import ast @@ -91,6 +94,13 @@ def get_members_value(context): return {"Other": value} +def is_filter_data(context): + for keyword in context.node.keywords: + if keyword.arg == "filter": + arg = keyword.value + return isinstance(arg, ast.Str) and arg.s == "data" + + @test.test_id("B202") @test.checks("Call") def tarfile_unsafe_members(context): @@ -100,6 +110,8 @@ def tarfile_unsafe_members(context): "extractall" in context.call_function_name, ] ): + if "filter" in context.call_keywords and is_filter_data(context): + return None if "members" in context.call_keywords: members = get_members_value(context) if "Function" in members: diff --git a/examples/tarfile_extractall.py b/examples/tarfile_extractall.py index 2af3eb544..b32736afb 100644 --- a/examples/tarfile_extractall.py +++ b/examples/tarfile_extractall.py @@ -15,6 +15,18 @@ def managed_members_archive_handler(filename): tar.close() +def filter_data_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), filter="data") + tar.close() + + +def filter_fully_trusted_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), filter="fully_trusted") + tar.close() + + def list_members_archive_handler(filename): tar = tarfile.open(filename) tar.extractall(path=tempfile.mkdtemp(), members=[]) @@ -45,3 +57,5 @@ def members_filter(tarfile): filename = sys.argv[1] unsafe_archive_handler(filename) managed_members_archive_handler(filename) + filter_data_archive_handler(filename) + filter_fully_trusted_archive_handler(filename) diff --git a/tests/functional/test_functional.py b/tests/functional/test_functional.py index a230dc30b..401c46f5f 100644 --- a/tests/functional/test_functional.py +++ b/tests/functional/test_functional.py @@ -926,7 +926,7 @@ def test_snmp_security_check(self): def test_tarfile_unsafe_members(self): """Test insecure usage of tarfile.""" expect = { - "SEVERITY": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 2, "HIGH": 1}, - "CONFIDENCE": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 2, "HIGH": 1}, + "SEVERITY": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 2, "HIGH": 2}, + "CONFIDENCE": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 2, "HIGH": 2}, } self.check_example("tarfile_extractall.py", expect)