From 6ffa739b70439736f4736709917b5c5bd8453bfb Mon Sep 17 00:00:00 2001 From: Tohar Braun Date: Tue, 5 Dec 2023 21:59:20 +0200 Subject: [PATCH 1/5] Lambda IAM InvokeFunction Misconfigured FP --- .../query.rego | 4 +++ .../test/negative3.tf | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/test/negative3.tf diff --git a/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/query.rego b/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/query.rego index 9c90b849f60..c79cf4db1d2 100644 --- a/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/query.rego +++ b/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/query.rego @@ -34,6 +34,10 @@ check_iam_ressource(statement) { is_array(statement.Resource) regex.match("(^arn:aws:lambda:.*:.*:function:[a-zA-Z0-9_-]+:[*]$)", statement.Resource[_]) regex.match("(^arn:aws:lambda:.*:.*:function:[a-zA-Z0-9_-]+$)", statement.Resource[_]) +} else { + is_array(statement.resources) + regex.match("(^aws_lambda_function\.[^.]\.arn:[*]$)", statement.resources[_]) + regex.match("(^aws_lambda_function\.[^.]\.arn$)", statement.resources[_]) } check_iam_action(statement) { diff --git a/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/test/negative3.tf b/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/test/negative3.tf new file mode 100644 index 00000000000..bb8b5c66105 --- /dev/null +++ b/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/test/negative3.tf @@ -0,0 +1,28 @@ +resource "aws_lambda_function" "negative3" { + function_name = "negative3" + role = "negative3_role" +} + +resource "aws_iam_policy" "negative2policy" { + name = "negative2policy" + path = "/" + description = "negative2 Policy" + + # Terraform's "jsonencode" function converts a + # Terraform expression result to valid JSON syntax. + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = [ + "s3:*", + ] + Effect = "Allow" + Resource = [ + aws_lambda_function.negative3.arn, + "${aws_lambda_function.negative3.arn}:*" + ] + }, + ] + }) +} From a156d16e1b5751b94842a50dc11a205787333b2a Mon Sep 17 00:00:00 2001 From: Tohar Braun Date: Tue, 5 Dec 2023 22:07:34 +0200 Subject: [PATCH 2/5] Lambda IAM InvokeFunction Misconfigured FP --- .../test/negative3.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/test/negative3.tf b/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/test/negative3.tf index bb8b5c66105..a68f09f5f4f 100644 --- a/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/test/negative3.tf +++ b/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/test/negative3.tf @@ -3,10 +3,10 @@ resource "aws_lambda_function" "negative3" { role = "negative3_role" } -resource "aws_iam_policy" "negative2policy" { - name = "negative2policy" +resource "aws_iam_policy" "negative3policy" { + name = "negative3policy" path = "/" - description = "negative2 Policy" + description = "negative3 Policy" # Terraform's "jsonencode" function converts a # Terraform expression result to valid JSON syntax. From 722cb125165e0e3de26355b04975fb2dd22797cb Mon Sep 17 00:00:00 2001 From: Tohar Braun Date: Wed, 13 Dec 2023 16:50:47 +0200 Subject: [PATCH 3/5] Fix false positive detections in "api_key_exposed" function --- assets/queries/ansible/aws/s3_bucket_sse_disabled/metadata.json | 2 +- .../cloudFormation/aws/s3_bucket_sse_disabled/metadata.json | 2 +- .../queries/terraform/aws/s3_bucket_sse_disabled/metadata.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/ansible/aws/s3_bucket_sse_disabled/metadata.json b/assets/queries/ansible/aws/s3_bucket_sse_disabled/metadata.json index 5c425fbb4ca..943b882d405 100644 --- a/assets/queries/ansible/aws/s3_bucket_sse_disabled/metadata.json +++ b/assets/queries/ansible/aws/s3_bucket_sse_disabled/metadata.json @@ -3,7 +3,7 @@ "queryName": "S3 Bucket SSE Disabled", "severity": "HIGH", "category": "Encryption", - "descriptionText": "If algorithm is AES256 then the master key is null, empty or undefined, otherwise the master key is required", + "descriptionText": "If master key is null, empty of undefined, then SSE algorithm should be AES25. Conversely, if SSE algorithm is AES256, then master key should be null, empty or undefined.", "descriptionUrl": "https://docs.ansible.com/ansible/latest/collections/amazon/aws/s3_bucket_module.html#parameter-encryption_key_id", "platform": "Ansible", "descriptionID": "4008dca4", diff --git a/assets/queries/cloudFormation/aws/s3_bucket_sse_disabled/metadata.json b/assets/queries/cloudFormation/aws/s3_bucket_sse_disabled/metadata.json index a99083e5366..0092b118fcf 100644 --- a/assets/queries/cloudFormation/aws/s3_bucket_sse_disabled/metadata.json +++ b/assets/queries/cloudFormation/aws/s3_bucket_sse_disabled/metadata.json @@ -3,7 +3,7 @@ "queryName": "S3 Bucket SSE Disabled", "severity": "HIGH", "category": "Encryption", - "descriptionText": "If algorithm is AES256 then the master key is null, empty or undefined, otherwise the master key is required", + "descriptionText": "If master key is null, empty of undefined, then SSE algorithm should be AES25. Conversely, if SSE algorithm is AES256, then master key should be null, empty or undefined.", "descriptionUrl": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-serversideencryptionbydefault.html", "platform": "CloudFormation", "descriptionID": "42fd2930", diff --git a/assets/queries/terraform/aws/s3_bucket_sse_disabled/metadata.json b/assets/queries/terraform/aws/s3_bucket_sse_disabled/metadata.json index 069d6b3b128..c69789ae0e2 100644 --- a/assets/queries/terraform/aws/s3_bucket_sse_disabled/metadata.json +++ b/assets/queries/terraform/aws/s3_bucket_sse_disabled/metadata.json @@ -3,7 +3,7 @@ "queryName": "S3 Bucket SSE Disabled", "severity": "HIGH", "category": "Encryption", - "descriptionText": "If algorithm is AES256 then the master key is null, empty or undefined, otherwise the master key is required", + "descriptionText": "If master key is null, empty of undefined, then SSE algorithm should be AES25. Conversely, if SSE algorithm is AES256, then master key should be null, empty or undefined.", "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#server_side_encryption_configuration", "platform": "Terraform", "descriptionID": "b386c506", From b2d8c63cd28fb7163ed8fcde11ae7094169a99aa Mon Sep 17 00:00:00 2001 From: Tohar Braun Date: Wed, 13 Dec 2023 17:36:25 +0200 Subject: [PATCH 4/5] Fix false positive detections in "api_key_exposed" function --- .../aws/lambda_iam_invokefunction_misconfigured/query.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/query.rego b/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/query.rego index c79cf4db1d2..d2512490ec9 100644 --- a/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/query.rego +++ b/assets/queries/terraform/aws/lambda_iam_invokefunction_misconfigured/query.rego @@ -36,8 +36,8 @@ check_iam_ressource(statement) { regex.match("(^arn:aws:lambda:.*:.*:function:[a-zA-Z0-9_-]+$)", statement.Resource[_]) } else { is_array(statement.resources) - regex.match("(^aws_lambda_function\.[^.]\.arn:[*]$)", statement.resources[_]) - regex.match("(^aws_lambda_function\.[^.]\.arn$)", statement.resources[_]) + regex.match("(^aws_lambda_function\\.[^.]\\.arn:[*]$)", statement.resources[_]) + regex.match("(^aws_lambda_function\\.[^.]\\.arn$)", statement.resources[_]) } check_iam_action(statement) { From 81b273d4cc284e8f7c4d202826b6fe0ce3fa4f33 Mon Sep 17 00:00:00 2001 From: Tohar Braun Date: Mon, 18 Dec 2023 20:19:06 +0200 Subject: [PATCH 5/5] Fix false positive detections in "api_gateway_with_cloudwatch_logging_disabled" --- .../query.rego | 3 ++- .../test/negative2.tf | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 assets/queries/terraform/aws/api_gateway_with_cloudwatch_logging_disabled/test/negative2.tf diff --git a/assets/queries/terraform/aws/api_gateway_with_cloudwatch_logging_disabled/query.rego b/assets/queries/terraform/aws/api_gateway_with_cloudwatch_logging_disabled/query.rego index 52baa0a7d1d..020029b2dab 100644 --- a/assets/queries/terraform/aws/api_gateway_with_cloudwatch_logging_disabled/query.rego +++ b/assets/queries/terraform/aws/api_gateway_with_cloudwatch_logging_disabled/query.rego @@ -19,6 +19,7 @@ CxPolicy[result] { haveLogs(stageName) { log := input.document[i].resource.aws_cloudwatch_log_group[_] - regexPattern := sprintf("API-Gateway-Execution-Logs_\\${aws_api_gateway_rest_api\\.\\w+\\.id}/%s$", [stageName]) + stageName_escaped := replace(replace(stageName, "$", "\\$"), ".", "\\.") + regexPattern := sprintf("API-Gateway-Execution-Logs_\\${aws_api_gateway_rest_api\\.\\w+\\.id}/%s$", [stageName_escaped]) regex.match(regexPattern, log.name) } diff --git a/assets/queries/terraform/aws/api_gateway_with_cloudwatch_logging_disabled/test/negative2.tf b/assets/queries/terraform/aws/api_gateway_with_cloudwatch_logging_disabled/test/negative2.tf new file mode 100644 index 00000000000..f0b125ae5a0 --- /dev/null +++ b/assets/queries/terraform/aws/api_gateway_with_cloudwatch_logging_disabled/test/negative2.tf @@ -0,0 +1,20 @@ +module "env" { + source = "./env" +} + +resource "aws_api_gateway_rest_api" "example" { + # ... other configuration ... +} + +resource "aws_api_gateway_stage" "example" { + depends_on = [aws_cloudwatch_log_group.example] + + stage_name = module.env.vars.stage_name + # ... other configuration ... +} + +resource "aws_cloudwatch_log_group" "example" { + name = "API-Gateway-Execution-Logs_${aws_api_gateway_rest_api.example.id}/${module.env.vars.stage_name}" + retention_in_days = 7 + # ... potentially other configuration ... +}