Repository: Checkmarx/kics (language: python)

Issue:
json: error calling MarshalJSON for type model.Document: value is not known
Found a bug? You're welcome to [![GitHub Discussions](https://img.shields.io/badge/chat-discussions-blue.svg?style=flat-square)](https://github.com/Checkmarx/kics/discussions)


- **Please make sure to:**
  - Describe in details what the problem is
  - Attach a log file with relevant data preferably in DEBUG level (`--log-level=DEBUG`)
  - Attach the scanned sample files, anonymize the data if the original file cannot be provided
  - When attaching files to the issue make sure they are properly formatted

when running a scan on the following TF file:
```
data "aws_iam_policy_document" "blabla" {
  statement {
    actions = [
      "secretsmanager:GetSecretValue",
    ]
    resources = [
      for s in [
        "DATABASE_READONLY_PASSWORD",
        "DATABASE_DATA_PASSWORD",
      ] : "arn:aws:secretsmanager:eu-west-1:${data.aws_caller_identity.this.account_id}:secret:/${var.env}/*/${s}-*"
    ]
  }
}
```
we are getting the following error:
```
Scanning with Keeping Infrastructure as Code Secure v1.7.4


1:45PM INF Scanning with Keeping Infrastructure as Code Secure v1.7.4
1:45PM INF Operating system: linux
1:45PM INF Total memory: 5.8G
1:45PM INF CPU: 5.0
1:45PM INF Total files in the project: 1
1:45PM INF Loading queries of type: terraform
1:45PM INF Inspector initialized, number of queries=1046
1:45PM INF Query execution timeout=1m0s
Preparing Scan Assets: Done
1:45PM ERR failed to marshal content in file: /path/bla.tf error="json: error calling MarshalJSON for type model.Document: value is not known"
Error: failed to read sources: failed to save file content: json: error calling MarshalJSON for type model.Document: value is not known
```



Discussion / hints:

Fix patch:
diff --git a/pkg/parser/terraform/converter/default.go b/pkg/parser/terraform/converter/default.go
index 67a6cf69389..3d728ce37c9 100644
--- a/pkg/parser/terraform/converter/default.go
+++ b/pkg/parser/terraform/converter/default.go
@@ -260,13 +260,27 @@ func (c *converter) convertExpression(expr hclsyntax.Expression) (interface{}, e
 			Variables: inputVarMap,
 			Functions: functions.TerraformFuncs,
 		})
-		if !valueConverted.Type().HasDynamicTypes() && valueConverted.IsKnown() {
+		if !checkDynamicKnownTypes(valueConverted) {
 			return ctyjson.SimpleJSONValue{Value: valueConverted}, nil
 		}
 		return c.wrapExpr(expr)
 	}
 }
 
+func checkDynamicKnownTypes(valueConverted cty.Value) bool {
+	if !valueConverted.Type().HasDynamicTypes() && valueConverted.IsKnown() {
+		if valueConverted.Type().FriendlyName() == "tuple" {
+			for _, val := range valueConverted.AsValueSlice() {
+				if val.Type().HasDynamicTypes() || !val.IsKnown() {
+					return true
+				}
+			}
+		}
+		return false
+	}
+	return true
+}
+
 func (c *converter) objectConsExpr(value *hclsyntax.ObjectConsExpr) (model.Document, error) {
 	m := make(model.Document)
 	for _, item := range value.Items {


Test patch:
diff --git a/pkg/parser/terraform/converter/default_test.go b/pkg/parser/terraform/converter/default_test.go
index b0753dbecef..c65c7627968 100644
--- a/pkg/parser/terraform/converter/default_test.go
+++ b/pkg/parser/terraform/converter/default_test.go
@@ -308,7 +308,7 @@ func TestEvalFunction(t *testing.T) { //nolint
 	}
 	tests := []funcTest{
 		{
-			name: "should evaluate without problems",
+			name: "should evaluate without problems (1)",
 			input: `
 block "label_one" {
 	policy = jsonencode({
@@ -387,6 +387,74 @@ block "label_one" {
 			  `,
 			wantErr: false,
 		},
+		{
+			name: "should evaluate without problems (2)",
+			input: `data "aws_iam_policy_document" "blabla" {
+	statement {
+	  actions = [
+		"secretsmanager:GetSecretValue",
+	  ]
+	  resources = [
+		for s in [
+		  "DATABASE_READONLY_PASSWORD",
+		  "DATABASE_DATA_PASSWORD",
+		] : "arn:aws:secretsmanager:eu-west-1:${data.aws_caller_identity.this.account_id}:secret:/${var.env}/*/${s}-*"
+	  ]
+	}
+  }
+`,
+			want: `
+			{
+				"data": {
+				  "aws_iam_policy_document": {
+					"blabla": {
+					  "statement": {
+						"resources": "${[\n\t\tfor s in [\n\t\t  \"DATABASE_READONLY_PASSWORD\",\n\t\t  \"DATABASE_DATA_PASSWORD\",\n\t\t] : \"arn:aws:secretsmanager:eu-west-1:${data.aws_caller_identity.this.account_id}:secret:/${var.env}/*/${s}-*\"\n\t  ]}",
+						"actions": [
+						  "secretsmanager:GetSecretValue"
+						],
+						"_kics_lines": {
+						  "_kics__default": {
+							"_kics_line": 2
+						  },
+						  "_kics_actions": {
+							"_kics_line": 3,
+							"_kics_arr": [
+							  {
+								"_kics__default": {
+								  "_kics_line": 4
+								}
+							  }
+							]
+						  },
+						  "_kics_resources": {
+							"_kics_line": 6
+						  }
+						}
+					  },
+					  "_kics_lines": {
+						"_kics__default": {
+						  "_kics_line": 1
+						},
+						"_kics_statement": {
+						  "_kics_line": 2
+						}
+					  }
+					}
+				  }
+				},
+				"_kics_lines": {
+				  "_kics__default": {
+					"_kics_line": 0
+				  },
+				  "_kics_data": {
+					"_kics_line": 1
+				  }
+				}
+			  }
+`,
+			wantErr: false,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {