diff --git a/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/notquery.rego b/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/notquery.rego deleted file mode 100644 index 60dba683ff9..00000000000 --- a/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/notquery.rego +++ /dev/null @@ -1,107 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib -import data.generic.common as common_lib -import future.keywords.every -import future.keywords.in - -CxPolicy[result] { - resource := input.document[i].resource.azurerm_storage_account[var0] - resource_name := tf_lib.get_resource_name(resource, var0) - networkRules := input.document[i].resource.azurerm_storage_account_network_rules[var1] - networkRules.storage_account_id == sprintf("${azurerm_storage_account.%s.id}", [var0]) - lower(networkRules.default_action) == "allow" - - result := { - "documentId": input.document[i].id, - "resourceType": "azurerm_storage_account", - "resourceName": resource_name, - "searchKey": sprintf("azurerm_storage_account_network_rules[%s].default_action", [var1]), - "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account_network_rules", var1, "default_action"], []), - "issueType": "IncorrectValue", - "keyExpectedValue": "azurerm_storage_account_network_rules.default_action should be set to 'Deny'", - "keyActualValue": "azurerm_storage_account_network_rules.default_action should be set to 'Allow'", - "remediation": json.marshal({ - "before": "Allow", - "after": "Deny", - }), - "remediationType": "replacement", - } -} - -CxPolicy[result] { - resource := input.document[i].resource.azurerm_storage_account[var0] - resource_name := tf_lib.get_resource_name(resource, var0) - not has_net_rules_obj(resource_name, input.document[i]) - net_rules := object.get(resource, "network_rules", {}) - lower(net_rules.default_action) == "allow" - - result := { - "documentId": input.document[i].id, - "resourceType": "azurerm_storage_account", - "resourceName": resource_name, - "searchKey": sprintf("azurerm_storage_account.network_rules[%s].default_action", [resource_name]), - "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", resource_name, "network_rules", "default_action"], []), - "issueType": "IncorrectValue", - "keyExpectedValue": "azurerm_storage_account.network_rules.default_action should be set to 'Deny'", - "keyActualValue": "azurerm_storage_account.network_rules.default_action should be set to 'Allow'", - "remediation": json.marshal({ - "before": "Allow", - "after": "Deny", - }), - "remediationType": "replacement", - } -} - -CxPolicy[result] { - resource := input.document[i].resource.azurerm_storage_account[var0] - resource_name := tf_lib.get_resource_name(resource, var0) - has_key(resource, "public_network_access_enabled") - resource.public_network_access_enabled - - result := { - "documentId": input.document[i].id, - "resourceType": "azurerm_storage_account", - "resourceName": resource_name, - "searchKey": sprintf("azurerm_storage_account[%s].public_network_access_enabled", [var0]), - "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", resource_name, "public_network_access_enabled"], []), - "issueType": "IncorrectValue", - "keyActualValue": "azurerm_storage_account.public_network_access_enabled is set to 'true'", - "keyExpectedValue": "azurerm_storage_account.public_network_access_enabled should be set to 'false'", - "remediation": json.marshal({ - "before": true, - "after": false, - }), - "remediationType": "replacement", - } -} - -CxPolicy[result] { - resource := input.document[i].resource.azurerm_storage_account[var0] - resource_name := tf_lib.get_resource_name(resource, var0) - not has_key(resource, "public_network_access_enabled") - - result := { - "documentId": input.document[i].id, - "resourceType": "azurerm_storage_account", - "resourceName": resource_name, - "searchKey": sprintf("azurerm_storage_account[%s].public_network_access_enabled", [var0]), - "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", resource_name, "public_network_access_enabled"], []), - "issueType": "IncorrectValue", - "keyActualValue": "azurerm_storage_account.public_network_access_enabled is not set (default is 'true')", - "keyExpectedValue": "azurerm_storage_account.public_network_access_enabled should be set to 'false'", - "remediation": "public_network_access_enabled = false", - "remediationType": "addition", - } -} - -has_key(x, k) { - _ = x[k] -} - -has_net_rules_obj(res_name, all_resources) = true { - has_key(all_resources, "azurerm_storage_account_network_rules") - every rule in all_resources.resource.azurerm_storage_account_network_rules { - rule.storage_account_id != sprintf("${azurerm_storage_account.%s.id}", [res_name]) - } -} else = false diff --git a/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/query.rego b/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/query.rego index 9d95feed8d1..9ccaf24c9a9 100644 --- a/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/query.rego +++ b/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/query.rego @@ -11,7 +11,7 @@ CxPolicy[result] { res1 := publicNetworkAccessEnabled(resource) res2 := aclsDefaultActionAllow(networkRules.rules) - issue := prepare_issue(res1, res2, var0, networkRules.type, networkRules.key) + issue := prepare_issue(res1, res2, var0, networkRules.type, networkRules.key, resource) result := { "documentId": input.document[i].id, @@ -27,7 +27,7 @@ CxPolicy[result] { } } -prepare_issue(res1, res2, resource_id, rules_type, rules_key) = issue { +prepare_issue(res1, res2, resource_id, rules_type, rules_key, resource) = issue { res1 == "not defined" res2 == "not defined" issue := { @@ -41,6 +41,7 @@ prepare_issue(res1, res2, resource_id, rules_type, rules_key) = issue { } } else = issue { res1 == "enabled" + not is_function_app(resource) issue := { "kav": "azurerm_storage_account.public_network_access_enabled set to 'true'", "kev": "azurerm_storage_account.public_network_access_enabled should be set to 'false'", @@ -126,3 +127,14 @@ aclsDefaultActionAllow(network_rules) = reason { has_key(x, k) { _ = x[k] } + +is_function_app(resource) { + common_lib.valid_key(resource, "tags") + is_object(resource.tags) + common_lib.valid_key(resource.tags, "bdo-attached-service") + resource.tags["bdo-attached-service"] == "function" +} else { + common_lib.valid_key(resource, "tags") + not is_object(resource.tags) + regex.match("(?i)bdo-attached-service[\"']?\\s*=?\\s*[\"']?function[\"']?", resource.tags) +} else = false \ No newline at end of file diff --git a/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/test/negative3.tf b/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/test/negative3.tf new file mode 100644 index 00000000000..e1470827428 --- /dev/null +++ b/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/test/negative3.tf @@ -0,0 +1,18 @@ +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_storage_account" "example" { + name = "positive3storageaccount" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "GRS" + public_network_access_enabled = true + + tags = { + environment = "staging" + bdo-attached-service = "function" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/test/negative4.tf b/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/test/negative4.tf new file mode 100644 index 00000000000..c8db8064e76 --- /dev/null +++ b/assets/queries/terraform/azure/default_azure_storage_account_network_access_is_too_permissive/test/negative4.tf @@ -0,0 +1,15 @@ +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_storage_account" "example" { + name = "positive3storageaccount" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "GRS" + public_network_access_enabled = true + + tags = merge(local.tags_resources, { "bdo-attached-service" = "function", bdo_name_service = "storage_account" }) +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/query.rego b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/query.rego index 0b22882a75b..fb99e9a085d 100644 --- a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/query.rego +++ b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/query.rego @@ -5,6 +5,7 @@ import data.generic.terraform as tf_lib CxPolicy[result] { resource := input.document[i].resource.azurerm_storage_account[name] + not is_function_app(resource) not common_lib.valid_key(resource, "network_rules") result := { @@ -15,6 +16,7 @@ CxPolicy[result] { "issueType": "MissingAttribute", "keyExpectedValue": "'network_rules' should be defined and not null", "keyActualValue": "'network_rules' is undefined or null", + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name], []), } } @@ -30,6 +32,7 @@ CxPolicy[result] { "issueType": "MissingAttribute", "keyExpectedValue": "'network_rules.bypass' should be defined and not null", "keyActualValue": "'network_rules.bypass' is undefined or null", + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name, "network_rules"], []), } } @@ -46,6 +49,7 @@ CxPolicy[result] { "issueType": "IncorrectValue", "keyExpectedValue": "'network_rules.bypass' should contain 'AzureServices'", "keyActualValue": "'network_rules.bypass' does not contain 'AzureServices'", + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name, "network_rules", "bypass"], []), } } @@ -61,6 +65,7 @@ CxPolicy[result] { "issueType": "MissingAttribute", "keyExpectedValue": "'bypass' should be defined and not null", "keyActualValue": "'bypass' is undefined or null", + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account_network_rules", name], []), } } @@ -77,5 +82,17 @@ CxPolicy[result] { "issueType": "IncorrectValue", "keyExpectedValue": "'bypass' should contain 'AzureServices'", "keyActualValue": "'bypass' does not contain 'AzureServices'", + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account_network_rules", name, "bypass"], []), } } + +is_function_app(resource) { + common_lib.valid_key(resource, "tags") + is_object(resource.tags) + common_lib.valid_key(resource.tags, "bdo-attached-service") + resource.tags["bdo-attached-service"] == "function" +} else { + common_lib.valid_key(resource, "tags") + not is_object(resource.tags) + regex.match("(?i)bdo-attached-service[\"']?\\s*=?\\s*[\"']?function[\"']?", resource.tags) +} else = false \ No newline at end of file diff --git a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative1.tf b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative1.tf new file mode 100644 index 00000000000..9b060a59db1 --- /dev/null +++ b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative1.tf @@ -0,0 +1,30 @@ +resource "azurerm_storage_account" "example" { + name = "storageaccountname" + resource_group_name = azurerm_resource_group.example.name + + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + + network_rules { + default_action = "Deny" + bypass = ["AzureServices"] + ip_rules = ["100.0.0.1"] + virtual_network_subnet_ids = [azurerm_subnet.example.id] + } + + tags = { + environment = "staging" + } +} + +resource "azurerm_storage_account_network_rules" "example" { + resource_group_name = azurerm_resource_group.test.name + storage_account_name = azurerm_storage_account.test.name + storage_account_id = azurerm_storage_account.example.id + + default_action = "Allow" + ip_rules = ["127.0.0.1"] + virtual_network_subnet_ids = [azurerm_subnet.test.id] + bypass = ["AzureServices"] +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative2.tf b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative2.tf new file mode 100644 index 00000000000..5525eaeb66b --- /dev/null +++ b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative2.tf @@ -0,0 +1,13 @@ +resource "azurerm_storage_account" "example" { + name = "storageaccountname" + resource_group_name = azurerm_resource_group.example.name + + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + + tags = { + environment = "staging" + bdo-attached-service = "function" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative3.tf b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative3.tf new file mode 100644 index 00000000000..51f5692e9b0 --- /dev/null +++ b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative3.tf @@ -0,0 +1,10 @@ +resource "azurerm_storage_account" "example" { + name = "storageaccountname" + resource_group_name = azurerm_resource_group.example.name + + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + + tags = merge(local.tags_resources, { "bdo-attached-service" = "function", bdo_name_service = "storage_account" }) +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative4.tf b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative4.tf new file mode 100644 index 00000000000..ebf7cd38cd0 --- /dev/null +++ b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative4.tf @@ -0,0 +1,30 @@ +resource "azurerm_storage_account" "example" { + name = "storageaccountname" + resource_group_name = azurerm_resource_group.example.name + + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + + network_rules { + default_action = "Deny" + bypass = ["AzureServices", "Metrics"] + ip_rules = ["100.0.0.1"] + virtual_network_subnet_ids = [azurerm_subnet.example.id] + } + + tags = { + environment = "staging" + } +} + +resource "azurerm_storage_account_network_rules" "example" { + resource_group_name = azurerm_resource_group.test.name + storage_account_name = azurerm_storage_account.test.name + storage_account_id = azurerm_storage_account.example.id + + default_action = "Allow" + ip_rules = ["127.0.0.1"] + virtual_network_subnet_ids = [azurerm_subnet.test.id] + bypass = ["AzureServices", "Metrics"] +} diff --git a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive.tf b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive1.tf similarity index 84% rename from assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive.tf rename to assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive1.tf index bb0837527ce..cf8a6035610 100644 --- a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive.tf +++ b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive1.tf @@ -1,4 +1,4 @@ -resource "azurerm_storage_account_network_rules" "positive1" { +resource "azurerm_storage_account_network_rules" "example" { resource_group_name = azurerm_resource_group.test.name storage_account_name = azurerm_storage_account.test.name @@ -8,7 +8,7 @@ resource "azurerm_storage_account_network_rules" "positive1" { bypass = ["Metrics"] } -resource "azurerm_storage_account" "positive2" { +resource "azurerm_storage_account" "example" { name = "storageaccountname" resource_group_name = azurerm_resource_group.example.name @@ -18,7 +18,7 @@ resource "azurerm_storage_account" "positive2" { network_rules { default_action = "Deny" - bypass = ["None"] + bypass = ["None"] ip_rules = ["100.0.0.1"] virtual_network_subnet_ids = [azurerm_subnet.example.id] } diff --git a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive2.tf b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive2.tf new file mode 100644 index 00000000000..764ca6b7ca4 --- /dev/null +++ b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive2.tf @@ -0,0 +1,12 @@ +resource "azurerm_storage_account" "example" { + name = "storageaccountname" + resource_group_name = azurerm_resource_group.example.name + + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + + tags = { + environment = "staging" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative.tf b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive3.tf similarity index 77% rename from assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative.tf rename to assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive3.tf index 73e32b563c1..77ec95565cc 100644 --- a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/negative.tf +++ b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive3.tf @@ -1,4 +1,14 @@ -resource "azurerm_storage_account" "negative1" { +resource "azurerm_storage_account_network_rules" "example" { + resource_group_name = azurerm_resource_group.test.name + storage_account_name = azurerm_storage_account.test.name + + default_action = "Allow" + ip_rules = ["127.0.0.1"] + virtual_network_subnet_ids = [azurerm_subnet.test.id] + bypass = ["Metrics", "Logging"] +} + +resource "azurerm_storage_account" "example" { name = "storageaccountname" resource_group_name = azurerm_resource_group.example.name @@ -8,7 +18,7 @@ resource "azurerm_storage_account" "negative1" { network_rules { default_action = "Deny" - bypass = ["AzureServices"] + bypass = ["None", "Logging"] ip_rules = ["100.0.0.1"] virtual_network_subnet_ids = [azurerm_subnet.example.id] } @@ -16,14 +26,4 @@ resource "azurerm_storage_account" "negative1" { tags = { environment = "staging" } -} - -resource "azurerm_storage_account_network_rules" "negative2" { - resource_group_name = azurerm_resource_group.test.name - storage_account_name = azurerm_storage_account.test.name - - default_action = "Allow" - ip_rules = ["127.0.0.1"] - virtual_network_subnet_ids = [azurerm_subnet.test.id] - bypass = ["Metrics", "AzureServices"] } \ No newline at end of file diff --git a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive4.tf b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive4.tf new file mode 100644 index 00000000000..db622c8fb48 --- /dev/null +++ b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive4.tf @@ -0,0 +1,27 @@ +resource "azurerm_storage_account_network_rules" "example" { + resource_group_name = azurerm_resource_group.test.name + storage_account_name = azurerm_storage_account.test.name + + default_action = "Allow" + ip_rules = ["127.0.0.1"] + virtual_network_subnet_ids = [azurerm_subnet.test.id] +} + +resource "azurerm_storage_account" "example" { + name = "storageaccountname" + resource_group_name = azurerm_resource_group.example.name + + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + + network_rules { + default_action = "Deny" + ip_rules = ["100.0.0.1"] + virtual_network_subnet_ids = [azurerm_subnet.example.id] + } + + tags = { + environment = "staging" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive_expected_result.json b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive_expected_result.json index 923845f4cad..0d5484d6628 100644 --- a/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/trusted_microsoft_services_not_enabled/test/positive_expected_result.json @@ -2,11 +2,43 @@ { "queryName": "Trusted Microsoft Services Not Enabled", "severity": "MEDIUM", - "line": 8 + "line": 8, + "filename": "positive1.tf" }, { "queryName": "Trusted Microsoft Services Not Enabled", "severity": "MEDIUM", - "line": 21 + "line": 21, + "filename": "positive1.tf" + }, + { + "queryName": "Trusted Microsoft Services Not Enabled", + "severity": "MEDIUM", + "line": 1, + "filename": "positive2.tf" + }, + { + "queryName": "Trusted Microsoft Services Not Enabled", + "severity": "MEDIUM", + "line": 8, + "filename": "positive3.tf" + }, + { + "queryName": "Trusted Microsoft Services Not Enabled", + "severity": "MEDIUM", + "line": 21, + "filename": "positive3.tf" + }, + { + "queryName": "Trusted Microsoft Services Not Enabled", + "severity": "MEDIUM", + "line": 1, + "filename": "positive4.tf" + }, + { + "queryName": "Trusted Microsoft Services Not Enabled", + "severity": "MEDIUM", + "line": 18, + "filename": "positive4.tf" } ] \ No newline at end of file