Repository: bridgecrewio/checkov

Issue:
Secrets check crashes when it encounters a dict
**Describe the issue**
Checkov scan is throwing error because of a dictionary structure in target files
**Examples**

In a Terraform file, add the following resource:
```
resource "aws_ssm_parameter" "aws_ssm_parameter_foo" {
  name        = "foo"
  description = "Parameter foo"
  type        = "String"
  tier        = "Advanced"
  value = jsonencode({
    "foo" : {
      "hello" : "world",
      "answer " : 42
     }
  })
}
```

**Exception Trace**
```
  File "/Python311/Lib/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/Python311/Lib/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Python311/site-packages/checkov/common/runners/runner_registry.py", line 125, in _parallel_run
    report = runner.run(
             ^^^^^^^^^^^
  File "/Python311/site-packages/checkov/terraform/runner.py", line 169, in run
    graph_report = self.get_graph_checks_report(root_folder, runner_filter)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Python311/site-packages/checkov/terraform/runner.py", line 256, in get_graph_checks_report
    censored_code_lines = omit_secret_value_from_graph_checks(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Python311/site-packages/checkov/common/util/secrets.py", line 213, in omit_secret_value_from_graph_checks
    secrets.add(secret[0])
TypeError: unhashable type: 'dict'
```

**Desktop (please complete the following information):**
 - OS: Windows 10 Pro for Workstation
 - Checkov Version 2.3.301

**Additional context**
None


Discussion:
hey @SKisContent thanks for reaching out.

I think you are using the `--mask` flag in `checkov` right? I will fix the crash, but it won't mask the value, just ignore it.
Thanks for looking into it! AFAIK, I am not using the `--mask` option. My flags are `--quiet` and `--compact`.
Interesting, can't reproduce it by just running `checkov`. Needed to use the `--mask` flag 😅  

Resolving patch:
diff --git a/checkov/common/util/secrets.py b/checkov/common/util/secrets.py
--- a/checkov/common/util/secrets.py
+++ b/checkov/common/util/secrets.py
@@ -4,8 +4,6 @@
 import json
 import logging
 import re
-
-# secret categories for use as constants
 from typing import Any, TYPE_CHECKING
 
 from checkov.common.models.enums import CheckCategories, CheckResult
@@ -17,7 +15,7 @@
     from checkov.common.typing import _CheckResult, ResourceAttributesToOmit
     from pycep.typing import ParameterAttributes, ResourceAttributes
 
-
+# secret categories for use as constants
 AWS = 'aws'
 AZURE = 'azure'
 GCP = 'gcp'
@@ -163,6 +161,10 @@ def omit_secret_value_from_checks(
             if key not in resource_masks:
                 continue
             if isinstance(secret, list) and secret:
+                if not isinstance(secret[0], str):
+                    logging.debug(f"Secret value can't be masked, has type {type(secret)}")
+                    continue
+
                 secrets.add(secret[0])
 
     if not secrets:
@@ -207,6 +209,10 @@ def omit_secret_value_from_graph_checks(
             for attribute, secret in entity_config.items():
                 if attribute in resource_masks:
                     if isinstance(secret, list) and secret:
+                        if not isinstance(secret[0], str):
+                            logging.debug(f"Secret value can't be masked, has type {type(secret)}")
+                            continue
+
                         secrets.add(secret[0])
 
     if not secrets:


Test patch:
diff --git a/tests/common/utils/test_secrets_utils.py b/tests/common/utils/test_secrets_utils.py
--- a/tests/common/utils/test_secrets_utils.py
+++ b/tests/common/utils/test_secrets_utils.py
@@ -114,6 +114,70 @@ def test_omit_secret_value_from_graph_checks_by_attribute(
     assert result == tfplan_resource_lines_without_secrets
 
 
+def test_omit_secret_value_from_graph_checks_by_attribute_skip_non_string():
+    # given
+    check = BaseGraphCheck()
+    check.resource_types = ['aws_ssm_parameter']
+    check_result = {'result': CheckResult.FAILED}
+    entity_code_lines = [
+        (22, 'resource "aws_ssm_parameter" "aws_ssm_parameter_foo" {\n'),
+        (23, '  name        = "foo"\n'),
+        (24, '  description = "Parameter foo"\n'),
+        (25, '  type        = "String"\n'),
+        (26, '  tier        = "Advanced"\n'),
+        (27, "  value = jsonencode({\n"),
+        (28, '    "foo" : {\n'),
+        (29, '      "hello" : "world",\n'),
+        (30, '      "answer " : 42\n'),
+        (31, "     }\n"),
+        (32, "  })\n"),
+        (33, "}\n"),
+    ]
+    entity_config = {
+        "__address__": "aws_ssm_parameter.aws_ssm_parameter_foo",
+        "__end_line__": 33,
+        "__start_line__": 22,
+        "description": ["Parameter foo"],
+        "name": ["foo"],
+        "tier": ["Advanced"],
+        "type": ["String"],
+        "value": [
+            {
+                "foo": {
+                    "answer ": 42,
+                    "hello": "world",
+                }
+            }
+        ],
+    }
+    resource_attributes_to_omit = {'aws_ssm_parameter': {'value'}}
+
+    # when
+    result = omit_secret_value_from_graph_checks(
+        check=check,
+        check_result=check_result,
+        entity_code_lines=entity_code_lines,
+        entity_config=entity_config,
+        resource_attributes_to_omit=resource_attributes_to_omit
+    )
+
+    # then
+    assert result == [
+        (22, 'resource "aws_ssm_parameter" "aws_ssm_parameter_foo" {\n'),
+        (23, '  name        = "foo"\n'),
+        (24, '  description = "Parameter foo"\n'),
+        (25, '  type        = "String"\n'),
+        (26, '  tier        = "Advanced"\n'),
+        (27, "  value = jsonencode({\n"),
+        (28, '    "foo" : {\n'),
+        (29, '      "hello" : "world",\n'),
+        (30, '      "answer " : 42\n'),
+        (31, "     }\n"),
+        (32, "  })\n"),
+        (33, "}\n"),
+    ]
+
+
 def test_omit_secret_value_from_checks_by_attribute_runner_filter_resource_config(
         tfplan_resource_lines_with_secrets,
         tfplan_resource_config_with_secrets,