From f8416190b654020028f3fe068af3fcb4b60fdb98 Mon Sep 17 00:00:00 2001 From: Rob Westbrook <105711620+tf-rob-w@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:19:11 +0100 Subject: [PATCH] fix(terraform): Added a check to make sure dynamic "blocks" are of the expected type (#5642) * fix-scalar-dynamic: Added a check to make sure dynamic "blocks" are actually of the correct type * fix-scalar-dynamic: Fixed typecheck --- checkov/terraform/parser_functions.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/checkov/terraform/parser_functions.py b/checkov/terraform/parser_functions.py index 16889e8b381..5cedd28bc38 100644 --- a/checkov/terraform/parser_functions.py +++ b/checkov/terraform/parser_functions.py @@ -7,7 +7,12 @@ from checkov.common.util.data_structures_utils import pickle_deepcopy from checkov.common.util.type_forcers import convert_str_to_bool -from checkov.common.util.parser_utils import eval_string, split_merge_args, string_to_native, to_string +from checkov.common.util.parser_utils import ( + eval_string, + split_merge_args, + string_to_native, + to_string, +) # # Functions defined in this file implement terraform functions. @@ -121,7 +126,7 @@ def toset(original: str, **_: Any) -> set[Any] | str: def tomap(original: str, **_: Any) -> dict[Hashable, Any] | str: # https://www.terraform.io/docs/language/functions/tomap.html - original = original.replace(":", "=") # converted to colons by parser #shrug + original = original.replace(":", "=") # converted to colons by parser #shrug altered_value = eval_string(original) if altered_value is None or not isinstance(altered_value, dict): @@ -136,7 +141,7 @@ def map(original: str, **_: Any) -> dict[Hashable, Any] | str: # the issue, act like it's a list (to allow comma separation) and let the HCL # parser deal with it. Then iterating the list is easy. converted_to_list = eval_string(f"[{original}]") - if converted_to_list is None or len(converted_to_list) & 1: # none or odd number of args + if converted_to_list is None or len(converted_to_list) & 1: # none or odd number of args return FUNCTION_FAILED return create_map(converted_to_list) @@ -190,8 +195,13 @@ def handle_dynamic_values(conf: Dict[str, List[Any]], has_dynamic_block: bool = def process_dynamic_values(conf: Dict[str, List[Any]]) -> bool: + dynamic_conf: Union[List[Any], Dict[str, List[Any]]] = conf.get("dynamic", {}) + + if not isinstance(dynamic_conf, list): + return False + has_dynamic_block = False - for dynamic_element in conf.get("dynamic", {}): + for dynamic_element in dynamic_conf: if isinstance(dynamic_element, str): try: dynamic_element = json.loads(dynamic_element)