diff --git a/bandit/plugins/general_bad_file_permissions.py b/bandit/plugins/general_bad_file_permissions.py index 7d3fce4df..2316a7615 100644 --- a/bandit/plugins/general_bad_file_permissions.py +++ b/bandit/plugins/general_bad_file_permissions.py @@ -53,6 +53,7 @@ Added checks for S_IWGRP and S_IXOTH """ # noqa: E501 +import ast import stat import bandit @@ -69,6 +70,24 @@ def _stat_is_dangerous(mode): ) +def _resolve_mode_from_ast(node): + if isinstance(node, ast.Constant) and isinstance(node.value, int): + return node.value + elif isinstance(node, getattr(ast, "Num", type(None))): + return getattr(node, "n", None) + elif isinstance(node, ast.Attribute): + if hasattr(stat, node.attr): + val = getattr(stat, node.attr) + if isinstance(val, int): + return val + elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr): + left = _resolve_mode_from_ast(node.left) + right = _resolve_mode_from_ast(node.right) + if left is not None and right is not None: + return left | right + return None + + @test.checks("Call") @test.test_id("B103") def set_bad_file_permissions(context): @@ -76,6 +95,10 @@ def set_bad_file_permissions(context): if context.call_args_count == 2: mode = context.get_call_arg_at_position(1) + if mode is None: + arg_node = context.node.args[1] + mode = _resolve_mode_from_ast(arg_node) + if ( mode is not None and isinstance(mode, int) diff --git a/examples/os-chmod.py b/examples/os-chmod.py index f7fff8517..c665ab2c8 100644 --- a/examples/os-chmod.py +++ b/examples/os-chmod.py @@ -17,3 +17,5 @@ os.chmod(keyfile, 0o777) os.chmod('~/hidden_exec', stat.S_IXGRP) os.chmod('~/hidden_exec', stat.S_IXOTH) +os.chmod('config.ini', stat.S_IWGRP | stat.S_IWOTH) +os.chmod('config.ini', stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IXOTH) diff --git a/tests/functional/test_functional.py b/tests/functional/test_functional.py index 08b1c5c5b..53181c1c7 100644 --- a/tests/functional/test_functional.py +++ b/tests/functional/test_functional.py @@ -269,8 +269,8 @@ def test_subdirectory_okay(self): def test_os_chmod(self): """Test setting file permissions.""" expect = { - "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 4, "HIGH": 8}, - "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 11}, + "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 5, "HIGH": 9}, + "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 13}, } self.check_example("os-chmod.py", expect)