From abac8d33d9048ec341bb6d23a589bd97f30e9f0d Mon Sep 17 00:00:00 2001 From: Eric Brown Date: Sat, 9 Jul 2022 16:55:29 -0700 Subject: [PATCH] Fix a false positive condition yaml_load The yaml.load() function has a second argument that is typically passed as a kwarg. However, someone could pass as a positional argument as well. In such a case, Bandit would flag code passing a SafeLoader even though that is validly secure. The fix involves looking at the positional args. However, the convenience function to do so also had no handling of ast.Attribute as args. So get_call_arg_at_position() was modified to function much like call_args(). Closes #546 Signed-off-by: Eric Brown --- bandit/core/context.py | 5 ++--- bandit/plugins/yaml_load.py | 2 ++ examples/yaml_load.py | 8 ++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/bandit/core/context.py b/bandit/core/context.py index 801b36466..1ecfb4495 100644 --- a/bandit/core/context.py +++ b/bandit/core/context.py @@ -276,9 +276,8 @@ def get_call_arg_at_position(self, position_num): """ max_args = self.call_args_count if max_args and position_num < max_args: - return self._get_literal_value( - self._context["call"].args[position_num] - ) + arg = self._context["call"].args[position_num] + return getattr(arg, "attr", None) or self._get_literal_value(arg) else: return None diff --git a/bandit/plugins/yaml_load.py b/bandit/plugins/yaml_load.py index acd67d727..2304c1d7d 100644 --- a/bandit/plugins/yaml_load.py +++ b/bandit/plugins/yaml_load.py @@ -62,6 +62,8 @@ def yaml_load(context): func == "load", not context.check_call_arg_value("Loader", "SafeLoader"), not context.check_call_arg_value("Loader", "CSafeLoader"), + not context.get_call_arg_at_position(1) == "SafeLoader", + not context.get_call_arg_at_position(1) == "CSafeLoader", ] ): return bandit.Issue( diff --git a/examples/yaml_load.py b/examples/yaml_load.py index 21d8797fc..a6a2eb164 100644 --- a/examples/yaml_load.py +++ b/examples/yaml_load.py @@ -1,5 +1,7 @@ import json import yaml +from yaml import CSafeLoader +from yaml import SafeLoader def test_yaml_load(): @@ -18,3 +20,9 @@ def test_json_load(): j = json.load("{}") yaml.load("{}", Loader=yaml.Loader) + +# no issue should be found +yaml.load("{}", SafeLoader) +yaml.load("{}", yaml.SafeLoader) +yaml.load("{}", CSafeLoader) +yaml.load("{}", yaml.CSafeLoader)