From 714b0358cb5fb71575bb4e43cce4008f07af1edc Mon Sep 17 00:00:00 2001 From: r4redu Date: Mon, 9 Aug 2021 23:11:57 -0700 Subject: [PATCH 1/8] verified registrieslist.rego --- azure/terraform/master-compliance-test.json | 4 ++-- azure/terraform/registrieslist.rego | 18 ++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/azure/terraform/master-compliance-test.json b/azure/terraform/master-compliance-test.json index f14bdc1d..c36f21f8 100644 --- a/azure/terraform/master-compliance-test.json +++ b/azure/terraform/master-compliance-test.json @@ -1722,12 +1722,12 @@ "id": "PR-AZR-0015-TRF", "eval": "data.rule.acr_classic", "message": "data.rule.acr_classic_err", - "remediationDescription": "", + "remediationDescription": "In 'azurerm_container_registry' resource, set the value to 'Basic'/'Standard'/'Premimu' other then 'classic' at property 'sku' to fix the issue. Visit https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_registry#sku for details.", "remediationFunction": "" } ], "severity": "Medium", - "title": "Azure Container Registry using the deprecated classic registry", + "title": "Azure Container Registry should not use the deprecated classic registry", "description": "This policy identifies an Azure Container Registry (ACR) that is using the classic SKU. The initial release of the Azure Container Registry (ACR) service that was offered as a classic SKU is being deprecated and will be unavailable after April 2019. As a best practice, upgrade your existing classic registry to a managed registry._x000D__x000D_For more information, visit https://docs.microsoft.com/en-us/azure/container-registry/container-registry-upgrade", "tags": [ { diff --git a/azure/terraform/registrieslist.rego b/azure/terraform/registrieslist.rego index 14d419dd..03aadd44 100644 --- a/azure/terraform/registrieslist.rego +++ b/azure/terraform/registrieslist.rego @@ -1,7 +1,7 @@ package rule # https://docs.microsoft.com/en-us/rest/api/containerregistry/registries/list - +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_registry # # PR-AZR-0015-TRF # @@ -22,24 +22,22 @@ azure_issue["acr_classic"] { acr_classic { lower(input.resources[_].type) == "azurerm_container_registry" - not azure_issue["acr_classic"] not azure_attribute_absence["acr_classic"] -} - -acr_classic = false { - azure_issue["acr_classic"] + not azure_issue["acr_classic"] } acr_classic = false { azure_attribute_absence["acr_classic"] } -acr_classic_err = "Azure Container Registry using the deprecated classic registry" { +acr_classic = false { azure_issue["acr_classic"] } -acr_classic_miss_err = "Azure Container registry attribute sku missing in the resource" { +acr_classic_err = "azurerm_container_registry property 'sku' need to be exist. Its missing from the resource." { azure_attribute_absence["acr_classic"] +} else = "Azure Container Registry currently using the deprecated classic registry." { + azure_issue["acr_classic"] } acr_classic_metadata := { @@ -47,9 +45,9 @@ acr_classic_metadata := { "Type": "IaC", "Product": "AZR", "Language": "Terraform", - "Policy Title": "Azure Container Registry using the deprecated classic registry", + "Policy Title": "Azure Container Registry should not use the deprecated classic registry", "Policy Description": "This policy identifies an Azure Container Registry (ACR) that is using the classic SKU. The initial release of the Azure Container Registry (ACR) service that was offered as a classic SKU is being deprecated and will be unavailable after April 2019. As a best practice, upgrade your existing classic registry to a managed registry._x005F_x000D_ _x005F_x000D_ For more information, visit https://docs.microsoft.com/en-us/azure/container-registry/container-registry-upgrade", "Resource Type": "azurerm_container_registry", "Policy Help URL": "", - "Resource Help URL": "https://docs.microsoft.com/en-us/rest/api/containerregistry/registries/list" + "Resource Help URL": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_registry" } From f84d0b55fa2a6c1a58a412bee256242788bdab1e Mon Sep 17 00:00:00 2001 From: r4redu Date: Mon, 9 Aug 2021 23:34:43 -0700 Subject: [PATCH 2/8] verified registrieswebhooks.rego --- azure/terraform/master-compliance-test.json | 4 ++-- azure/terraform/registrieswebhooks.rego | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/azure/terraform/master-compliance-test.json b/azure/terraform/master-compliance-test.json index c36f21f8..87a7e201 100644 --- a/azure/terraform/master-compliance-test.json +++ b/azure/terraform/master-compliance-test.json @@ -1751,12 +1751,12 @@ "id": "PR-AZR-0005-TRF", "eval": "data.rule.acr_webhooks", "message": "data.rule.acr_webhooks_err", - "remediationDescription": "", + "remediationDescription": "In 'azurerm_container_registry_webhook' resource, set secure http (https) based wekhook url at 'service_uri' property to fix the issue. Visit https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_registry_webhook#service_uri for details.", "remediationFunction": "" } ], "severity": "Medium", - "title": "Azure ACR HTTPS not enabled for webhook", + "title": "Azure ACR should have HTTPS protocol enabled for webhook", "description": "Ensure you send container registry webhooks only to a HTTPS endpoint. This policy checks your container registry webhooks and alerts if it finds a URI with HTTP.", "tags": [ { diff --git a/azure/terraform/registrieswebhooks.rego b/azure/terraform/registrieswebhooks.rego index 7a685a11..fe7f4ee6 100644 --- a/azure/terraform/registrieswebhooks.rego +++ b/azure/terraform/registrieswebhooks.rego @@ -1,7 +1,7 @@ package rule # https://docs.microsoft.com/en-us/azure/templates/azurerm_container_registry_webhook - +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_registry_webhook # # PR-AZR-0005-TRF # @@ -22,24 +22,26 @@ azure_issue["acr_webhooks"] { acr_webhooks { lower(input.resources[_].type) == "azurerm_container_registry_webhook" - not azure_issue["acr_webhooks"] not azure_attribute_absence["acr_webhooks"] + not azure_issue["acr_webhooks"] } acr_webhooks = false { - azure_issue["acr_webhooks"] + azure_attribute_absence["acr_webhooks"] } acr_webhooks = false { - azure_attribute_absence["acr_webhooks"] + azure_issue["acr_webhooks"] } -acr_webhooks_err = "Azure ACR HTTPS not enabled for webhook" { +acr_webhooks_err = "azurerm_container_registry_webhook property 'service_uri' need to be exist. Its missing from the resource." { + azure_attribute_absence["acr_webhooks"] +} else = "Azure ACR currently does not have HTTPS protocol enabled for webhook" { azure_issue["acr_webhooks"] } acr_webhooks_miss_err = "Container registy webhook attribute service_uri missing in the resource" { - azure_attribute_absence["acr_webhooks"] + } acr_webhooks_metadata := { @@ -47,9 +49,9 @@ acr_webhooks_metadata := { "Type": "IaC", "Product": "AZR", "Language": "Terraform", - "Policy Title": "Azure ACR HTTPS not enabled for webhook", + "Policy Title": "Azure ACR should have HTTPS protocol enabled for webhook", "Policy Description": "Ensure you send container registry webhooks only to a HTTPS endpoint. This policy checks your container registry webhooks and alerts if it finds a URI with HTTP.", "Resource Type": "azurerm_container_registry_webhook", "Policy Help URL": "", - "Resource Help URL": "https://docs.microsoft.com/en-us/azure/templates/azurerm_container_registry_webhook" + "Resource Help URL": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_registry_webhook" } From f5a5a6f54a66c93252e29cc463478a276d724497 Mon Sep 17 00:00:00 2001 From: r4redu Date: Tue, 10 Aug 2021 00:07:56 -0700 Subject: [PATCH 3/8] verified securitycontacts.rego --- azure/iac/master-compliance-test.json | 4 ++-- azure/iac/registrieslist.rego | 2 +- azure/iac/registrieswebhooks.rego | 2 +- azure/iac/securitycontacts.rego | 4 ++-- azure/terraform/master-compliance-test.json | 4 ++-- azure/terraform/securitycontacts.rego | 18 ++++++++---------- 6 files changed, 16 insertions(+), 18 deletions(-) diff --git a/azure/iac/master-compliance-test.json b/azure/iac/master-compliance-test.json index 186b9339..1651bcad 100644 --- a/azure/iac/master-compliance-test.json +++ b/azure/iac/master-compliance-test.json @@ -2364,7 +2364,7 @@ } ], "severity": "Medium", - "title": "Azure Container Registry shoud not have deprecated classic SKU configured", + "title": "Azure Container Registry should not use the deprecated classic registry", "description": "This policy identifies an Azure Container Registry (ACR) that is using the classic SKU. The initial release of the Azure Container Registry (ACR) service that was offered as a classic SKU is being deprecated and will be unavailable after April 2019. As a best practice, upgrade your existing classic registry to a managed registry._x000D__x000D_For more information, visit https://docs.microsoft.com/en-us/azure/container-registry/container-registry-upgrade", "tags": [ { @@ -2393,7 +2393,7 @@ } ], "severity": "Medium", - "title": "Azure ACR webhook should have HTTPS protocol enabled", + "title": "Azure ACR should have HTTPS protocol enabled for webhook", "description": "Ensure you send container registry webhooks only to a HTTPS endpoint. This policy checks your container registry webhooks and alerts if it finds a URI with HTTP.", "tags": [ { diff --git a/azure/iac/registrieslist.rego b/azure/iac/registrieslist.rego index cce62f58..1b2abb56 100644 --- a/azure/iac/registrieslist.rego +++ b/azure/iac/registrieslist.rego @@ -47,7 +47,7 @@ acr_classic_metadata := { "Type": "IaC", "Product": "AZR", "Language": "ARM template", - "Policy Title": "Azure Container Registry shoud not have deprecated classic SKU configured", + "Policy Title": "Azure Container Registry should not use the deprecated classic registry", "Policy Description": "This policy identifies an Azure Container Registry (ACR) that is using the classic SKU. The initial release of the Azure Container Registry (ACR) service that was offered as a classic SKU is being deprecated and will be unavailable after April 2019. As a best practice, upgrade your existing classic registry to a managed registry._x005F_x000D_ _x005F_x000D_ For more information, visit https://docs.microsoft.com/en-us/azure/container-registry/container-registry-upgrade", "Resource Type": "microsoft.containerregistry/registries", "Policy Help URL": "", diff --git a/azure/iac/registrieswebhooks.rego b/azure/iac/registrieswebhooks.rego index 83992e1e..43f0cebd 100644 --- a/azure/iac/registrieswebhooks.rego +++ b/azure/iac/registrieswebhooks.rego @@ -47,7 +47,7 @@ acr_webhooks_metadata := { "Type": "IaC", "Product": "AZR", "Language": "ARM template", - "Policy Title": "Azure ACR webhook should have HTTPS protocol enabled", + "Policy Title": "Azure ACR should have HTTPS protocol enabled for webhook", "Policy Description": "Ensure you send container registry webhooks only to a HTTPS endpoint. This policy checks your container registry webhooks and alerts if it finds a URI with HTTP.", "Resource Type": "microsoft.containerregistry/registries/webhooks", "Policy Help URL": "", diff --git a/azure/iac/securitycontacts.rego b/azure/iac/securitycontacts.rego index e3874118..5156d2be 100644 --- a/azure/iac/securitycontacts.rego +++ b/azure/iac/securitycontacts.rego @@ -34,11 +34,11 @@ securitycontacts = false { azure_attribute_absence["securitycontacts"] } -securitycontacts_err = "Security Center currently dont have any security contact emails configured" { +securitycontacts_err = "Security Center currently does not have any valid security contact email configured" { azure_issue["securitycontacts"] } -securitycontacts_miss_err = "Security Center security contacts property 'mail' is missing from the resource" { +securitycontacts_miss_err = "Security Center security contacts property 'emails' is missing from the resource" { azure_attribute_absence["securitycontacts"] } diff --git a/azure/terraform/master-compliance-test.json b/azure/terraform/master-compliance-test.json index 87a7e201..7dbb4f8e 100644 --- a/azure/terraform/master-compliance-test.json +++ b/azure/terraform/master-compliance-test.json @@ -1780,12 +1780,12 @@ "id": "PR-AZR-0087-TRF", "eval": "data.rule.securitycontacts", "message": "data.rule.securitycontacts_err", - "remediationDescription": "", + "remediationDescription": "In 'azurerm_security_center_contact' resource, set a valid email address at 'email' property to fix the issue. Visit https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/security_center_contact#email for details.", "remediationFunction": "" } ], "severity": "Medium", - "title": "Security contact emails is not set in Security Center", + "title": "Security Center shoud have security contact email configured to get notifications", "description": "Setting a valid email address in Security contact emails will enable Microsoft to contact you if the Microsoft Security Response Center (MSRC) discovers that your data has been accessed by an unlawful or unauthorized party. This will make sure that you are aware of any security issues and take prompt actions to mitigate the risks.", "tags": [ { diff --git a/azure/terraform/securitycontacts.rego b/azure/terraform/securitycontacts.rego index f6cf8481..28c625bc 100644 --- a/azure/terraform/securitycontacts.rego +++ b/azure/terraform/securitycontacts.rego @@ -1,7 +1,7 @@ package rule # https://docs.microsoft.com/en-us/azure/templates/azurerm_security_center_contact - +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/security_center_contact # # PR-AZR-0087-TRF # @@ -22,24 +22,22 @@ azure_issue["securitycontacts"] { securitycontacts { lower(input.resources[_].type) == "azurerm_security_center_contact" - not azure_issue["securitycontacts"] not azure_attribute_absence["securitycontacts"] -} - -securitycontacts = false { - azure_issue["securitycontacts"] + not azure_issue["securitycontacts"] } securitycontacts = false { azure_attribute_absence["securitycontacts"] } -securitycontacts_err = "Security contact emails is not set in Security Center" { +securitycontacts = false { azure_issue["securitycontacts"] } -securitycontacts_miss_err = "Security Contacts attribute mail missing in the resource" { +securitycontacts_err = "azurerm_security_center_contact property 'email' need to be exist. Its missing from the resource. Please set a valid email address as value after property addition." { azure_attribute_absence["securitycontacts"] +} else = "Security Center currently does not have any valid security contact email configured" { + azure_issue["securitycontacts"] } securitycontacts_metadata := { @@ -47,9 +45,9 @@ securitycontacts_metadata := { "Type": "IaC", "Product": "AZR", "Language": "Terraform", - "Policy Title": "Security contact emails is not set in Security Center", + "Policy Title": "Security Center shoud have security contact email configured to get notifications", "Policy Description": "Setting a valid email address in Security contact emails will enable Microsoft to contact you if the Microsoft Security Response Center (MSRC) discovers that your data has been accessed by an unlawful or unauthorized party. This will make sure that you are aware of any security issues and take prompt actions to mitigate the risks.", "Resource Type": "azurerm_security_center_contact", "Policy Help URL": "", - "Resource Help URL": "https://docs.microsoft.com/en-us/azure/templates/azurerm_security_center_contact" + "Resource Help URL": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/security_center_contact" } From c0bb2b70caf204462d78f420ce95e0b22b5ed94f Mon Sep 17 00:00:00 2001 From: r4redu Date: Tue, 10 Aug 2021 01:00:59 -0700 Subject: [PATCH 4/8] verified sql_servers.rego and removed sql_managedinstance.rego file as there is no resource avialable for Azure MI in terraform yet. --- azure/iac/sql_servers.rego | 2 +- azure/terraform/master-compliance-test.json | 36 ++++++++++++ azure/terraform/sql_managedinstance.rego | 40 -------------- azure/terraform/sql_servers.rego | 61 ++++++++++++++++++++- 4 files changed, 95 insertions(+), 44 deletions(-) delete mode 100644 azure/terraform/sql_managedinstance.rego diff --git a/azure/iac/sql_servers.rego b/azure/iac/sql_servers.rego index 84c370b4..19deb8e8 100644 --- a/azure/iac/sql_servers.rego +++ b/azure/iac/sql_servers.rego @@ -38,7 +38,7 @@ sql_public_access_disabled_miss_err = "publicNetworkAccess property is missing f azure_attribute_absence["sql_public_access_disabled"] } -sql_public_access_disabled_err = "Public Network Access is currently not disabled on the resource" { +sql_public_access_disabled_err = "Public Network Access is currently not disabled on MSSQL Server" { azure_issue["sql_public_access_disabled"] } diff --git a/azure/terraform/master-compliance-test.json b/azure/terraform/master-compliance-test.json index 7dbb4f8e..d36c2c41 100644 --- a/azure/terraform/master-compliance-test.json +++ b/azure/terraform/master-compliance-test.json @@ -1804,6 +1804,42 @@ } ] }, + { + "masterTestId": "TEST_MSSQL_SERVER", + "masterSnapshotId": [ + "TRF_TEMPLATE_SNAPSHOT" + ], + "type": "rego", + "rule": "file(sql_servers.rego)", + "evals": [ + { + "id": "PR-AZR-0126-TRF", + "eval": "data.rule.sql_public_access_disabled", + "message": "data.rule.sql_public_access_disabled_err", + "remediationDescription": "In 'azurerm_mssql_server' resource, set 'public_network_access_enabled = false' to fix the issue. If 'public_network_access_enabled' property does not exist please add it. Visit https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mssql_server#public_network_access_enabled for details.", + "remediationFunction": "" + } + ], + "severity": "High", + "title": "Ensure SQL servers don't have public network access enabled", + "description": "Always use Private Endpoint for Azure SQL Database and SQL Managed Instance", + "tags": [ + { + "cloud": "git", + "compliance": [ + "CIS", + "CSA-CCM", + "HIPAA", + "ISO 27001", + "NIST 800", + "PCI-DSS" + ], + "service": [ + "terraform" + ] + } + ] + }, { "masterTestId": "TEST_STORAGE_ACCOUNT_1", "masterSnapshotId": [ diff --git a/azure/terraform/sql_managedinstance.rego b/azure/terraform/sql_managedinstance.rego deleted file mode 100644 index cb7ed095..00000000 --- a/azure/terraform/sql_managedinstance.rego +++ /dev/null @@ -1,40 +0,0 @@ -package rule - -# https://docs.microsoft.com/en-us/azure/templates/azurerm_mssql_server - -# -# Always use Private Endpoint for Azure SQL Database and SQL Managed Instance -# - -default sql_public_endpoint = null - -azure_issue["sql_public_endpoint"] { - resource := input.resources[_] - lower(resource.type) == "azurerm_mssql_server" - resource.properties.public_network_access_enabled != false -} - -sql_public_endpoint { - lower(input.resources[_].type) == "azurerm_mssql_server" - not azure_issue["sql_public_endpoint"] -} - -sql_public_endpoint = false { - azure_issue["sql_public_endpoint"] -} - -sql_public_endpoint_err = "SQL Managed Instance with enabled public endpoint detected!" { - azure_issue["sql_public_endpoint"] -} - -sql_public_endpoint_metadata := { - "Policy Code": "", - "Type": "IaC", - "Product": "", - "Language": "Terraform", - "Policy Title": "SQL Managed Instance with enabled public endpoint detected!", - "Policy Description": "Always use Private Endpoint for Azure SQL Database and SQL Managed Instance", - "Resource Type": "azurerm_mssql_server", - "Policy Help URL": "", - "Resource Help URL": "https://docs.microsoft.com/en-us/azure/templates/azurerm_mssql_server" -} diff --git a/azure/terraform/sql_servers.rego b/azure/terraform/sql_servers.rego index 27e799b9..4a7c1fb8 100644 --- a/azure/terraform/sql_servers.rego +++ b/azure/terraform/sql_servers.rego @@ -1,11 +1,65 @@ package rule -# https://docs.microsoft.com/en-us/azure/templates/azurerm_sql_server +# https://docs.microsoft.com/en-us/azure/templates/azurerm_mssql_server # -# Always use Private Endpoint for Azure SQL Database and SQL Managed Instance +# Always use Private Endpoint for Azure MSSQL Database and SQL Managed Instance (SQL MI resource is not available for terraform yet. visit: https://github.com/hashicorp/terraform-provider-azurerm/issues/1747) # +# PR-AZR-0126-TRF + +default sql_public_access_disabled = null + +azure_attribute_absence["sql_public_access_disabled"] { + resource := input.resources[_] + lower(resource.type) == "azurerm_mssql_server" + not resource.properties.public_network_access_enabled +} + +azure_issue["sql_public_access_disabled"] { + resource := input.resources[_] + lower(resource.type) == "azurerm_mssql_server" + resource.properties.public_network_access_enabled != false +} + +sql_public_access_disabled { + lower(input.resources[_].type) == "azurerm_mssql_server" + not azure_attribute_absence["sql_public_access_disabled"] + not azure_issue["sql_public_access_disabled"] +} + +sql_public_access_disabled = false { + azure_attribute_absence["sql_public_access_disabled"] +} + +sql_public_access_disabled = false { + azure_issue["sql_public_access_disabled"] +} + +sql_public_access_disabled_err = "azurerm_mssql_server property 'public_network_access_enabled' need to be exist. Its missing from the resource. Please set the value to 'false' after property addition." { + azure_attribute_absence["sql_public_access_disabled"] +} else = "Public Network Access is currently not disabled on MSSQL Server." { + azure_issue["sql_public_access_disabled"] +} + +sql_public_access_disabled_metadata := { + "Policy Code": "PR-AZR-0126-TRF", + "Type": "IaC", + "Product": "AZR", + "Language": "Terraform", + "Policy Title": "Ensure SQL servers don't have public network access enabled", + "Policy Description": "Always use Private Endpoint for Azure SQL Database and SQL Managed Instance", + "Resource Type": "azurerm_mssql_server", + "Policy Help URL": "", + "Resource Help URL": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mssql_server" +} + +# https://docs.microsoft.com/en-us/azure/templates/azurerm_sql_server +# Always use Private Endpoint for Azure SQL Database and SQL Managed Instance +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/sql_server +# This resource provides usage of Microsoft SQL Azure Database server using an older sku based model. +# It is recommended going forward to use azurerm_mssql_server resource which provides support for vcores. +# (code is kept for reference but not used anywhere) default sql_public_access = null azure_issue["sql_public_access"] { @@ -36,5 +90,6 @@ sql_public_access_metadata := { "Policy Description": "Always use Private Endpoint for Azure SQL Database and SQL Managed Instance", "Resource Type": "azurerm_sql_server", "Policy Help URL": "", - "Resource Help URL": "https://docs.microsoft.com/en-us/azure/templates/azurerm_sql_server" + "Resource Help URL": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/sql_server" } + From 7dab9727f5d9e457dbb546fb6acc76213ae0b10f Mon Sep 17 00:00:00 2001 From: r4redu Date: Tue, 10 Aug 2021 03:13:06 -0700 Subject: [PATCH 5/8] verfied storageaccounts.rego --- azure/terraform/master-compliance-test.json | 14 ++--- azure/terraform/storageaccounts.rego | 58 ++++++++++----------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/azure/terraform/master-compliance-test.json b/azure/terraform/master-compliance-test.json index d36c2c41..8c318684 100644 --- a/azure/terraform/master-compliance-test.json +++ b/azure/terraform/master-compliance-test.json @@ -1852,12 +1852,12 @@ "id": "PR-AZR-0092-TRF", "eval": "data.rule.storage_secure", "message": "data.rule.storage_secure_err", - "remediationDescription": "", + "remediationDescription": "In 'azurerm_storage_account' resource, set 'enable_https_traffic_only = true' or remove property 'enable_https_traffic_only' to fix the issue. Visit https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#enable_https_traffic_only for details.", "remediationFunction": "" } ], "severity": "Medium", - "title": "Storage Accounts Secure transfer should be enabled", + "title": "Storage Accounts https based secure transfer should be enabled", "description": "The secure transfer option enhances the security of your storage account by only allowing requests to the storage account by a secure connection. For example, when calling REST APIs to access your storage accounts, you must connect using HTTPs. Any requests using HTTP will be rejected when 'secure transfer required' is enabled. When you are using the Azure files service, connection without encryption will fail, including scenarios using SMB 2.1, SMB 3.0 without encryption, and some flavors of the Linux SMB client. Because Azure storage doesn’t support HTTPs for custom domain names, this option is not applied when using a custom domain name.", "tags": [ { @@ -1888,12 +1888,12 @@ "id": "PR-AZR-0093-TRF", "eval": "data.rule.storage_acl", "message": "data.rule.storage_acl_err", - "remediationDescription": "", + "remediationDescription": "In 'azurerm_storage_account_network_rules' resource, set 'default_action = Deny' to fix the issue. Visit https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account_network_rules#default_action for details.", "remediationFunction": "" } ], "severity": "Medium", - "title": "Storage Accounts without their firewalls enabled (TJX)", + "title": "Storage Accounts should have firewall rules enabled", "description": "Turning on firewall rules for your storage account blocks incoming requests for data by default, unless the requests come from a service that is operating within an Azure Virtual Network (VNet). Requests that are blocked include those from other Azure services, from the Azure portal, from logging and metrics services, and so on._x000D__x000D_You can grant access to Azure services that operate from within a VNet by allowing the subnet of the service instance. Enable a limited number of scenarios through the Exceptions mechanism described in the following section. To access the Azure portal, you would need to be on a machine within the trusted boundary (either IP or VNet) that you set up.", "tags": [ { @@ -1919,15 +1919,15 @@ "rule": "file(storageaccounts.rego)", "evals": [ { - "id": "PR-AZR-0069-TRF", + "id": "PR-AZR-0123-TRF", "eval": "data.rule.storage_account_public_access_disabled", "message": "data.rule.storage_account_public_access_disabled_err", - "remediationDescription": "", + "remediationDescription": "In 'azurerm_storage_account' resource, set 'allow_blob_public_access = false' to fix the issue. Visit https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#allow_blob_public_access for details.", "remediationFunction": "" } ], "severity": "High", - "title": "Storage Account should not allow public access to all blobs or containers", + "title": "Ensure that Storage Account should not allow public access to all blobs or containers", "description": "This policy will identify which Storage Account has public access not disabled for all blobs or containers and alert", "tags": [ { diff --git a/azure/terraform/storageaccounts.rego b/azure/terraform/storageaccounts.rego index 07d9b0be..86f2a35f 100644 --- a/azure/terraform/storageaccounts.rego +++ b/azure/terraform/storageaccounts.rego @@ -35,7 +35,7 @@ storage_secure = false { azure_issue["storage_secure"] } -storage_secure_err = "Storage Accounts without Secure transfer enabled" { +storage_secure_err = "Storage Accounts https based secure transfer is not enabled" { azure_issue["storage_secure"] } @@ -44,16 +44,17 @@ storage_secure_metadata := { "Type": "IaC", "Product": "AZR", "Language": "Terraform", - "Policy Title": "Storage Accounts Secure transfer should be enabled", + "Policy Title": "Storage Accounts https based secure transfer should be enabled", "Policy Description": "The secure transfer option enhances the security of your storage account by only allowing requests to the storage account by a secure connection. For example, when calling REST APIs to access your storage accounts, you must connect using HTTPs. Any requests using HTTP will be rejected when 'secure transfer required' is enabled. When you are using the Azure files service, connection without encryption will fail, including scenarios using SMB 2.1, SMB 3.0 without encryption, and some flavors of the Linux SMB client. Because Azure storage doesn’t support HTTPs for custom domain names, this option is not applied when using a custom domain name.", "Resource Type": "azurerm_storage_account", "Policy Help URL": "", - "Resource Help URL": "https://docs.microsoft.com/en-us/azure/templates/azurerm_storage_account" + "Resource Help URL": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account" } + # # PR-AZR-0093-TRF -# +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account_network_rules default storage_acl = null @@ -71,24 +72,23 @@ azure_issue["storage_acl"] { storage_acl { lower(input.resources[_].type) == "azurerm_storage_account_network_rules" - not azure_issue["storage_acl"] not azure_attribute_absence["storage_acl"] -} - -storage_acl = false { - azure_issue["storage_acl"] + not azure_issue["storage_acl"] } storage_acl = false { azure_attribute_absence["storage_acl"] } -storage_acl_err = "Storage Accounts without their firewalls enabled" { +storage_acl = false { azure_issue["storage_acl"] } -storage_acl_miss_err = "Storage Account attribute default_action missing in the resource" { + +storage_acl_err = "azurerm_storage_account_network_rules property 'default_action' need to be exist. Its missing from the resource. Please set the value to 'deny' after property addition." { azure_attribute_absence["storage_acl"] +} else = "Storage Accounts firewall rule is currently not enabled" { + azure_issue["storage_acl"] } storage_acl_metadata := { @@ -96,25 +96,24 @@ storage_acl_metadata := { "Type": "IaC", "Product": "AZR", "Language": "Terraform", - "Policy Title": "Storage Accounts without their firewalls enabled (TJX)", + "Policy Title": "Storage Accounts should have firewall rules enabled", "Policy Description": "Turning on firewall rules for your storage account blocks incoming requests for data by default, unless the requests come from a service that is operating within an Azure Virtual Network (VNet). Requests that are blocked include those from other Azure services, from the Azure portal, from logging and metrics services, and so on._x005F_x000D_ _x005F_x000D_ You can grant access to Azure services that operate from within a VNet by allowing the subnet of the service instance. Enable a limited number of scenarios through the Exceptions mechanism described in the following section. To access the Azure portal, you would need to be on a machine within the trusted boundary (either IP or VNet) that you set up.", "Resource Type": "azurerm_storage_account_network_rules", "Policy Help URL": "", - "Resource Help URL": "https://docs.microsoft.com/en-us/azure/templates/azurerm_storage_account" + "Resource Help URL": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account_network_rules" } # -# PR-AZR-0069-TRF -# +# PR-AZR-0123-TRF default storage_account_public_access_disabled = null -# Required property and defaults to false -#azure_attribute_absence["storage_secure"] { -# resource := input.resources[_] -# lower(resource.type) == "azurerm_storage_account" -# not resource.properties.allow_blob_public_access -#} +# defaults to false +azure_attribute_absence["storage_account_public_access_disabled"] { + resource := input.resources[_] + lower(resource.type) == "azurerm_storage_account" + not resource.properties.allow_blob_public_access +} azure_issue["storage_account_public_access_disabled"] { resource := input.resources[_] @@ -124,29 +123,30 @@ azure_issue["storage_account_public_access_disabled"] { storage_account_public_access_disabled { lower(input.resources[_].type) == "azurerm_storage_account" + not azure_attribute_absence["storage_account_public_access_disabled"] not azure_issue["storage_account_public_access_disabled"] } +storage_account_public_access_disabled { + azure_attribute_absence["storage_account_public_access_disabled"] +} + storage_account_public_access_disabled = false { azure_issue["storage_account_public_access_disabled"] } -#storage_account_public_access_disabled { -# azure_attribute_absence["storage_account_public_access_disabled"] -#} - -storage_account_public_access_disabled_err = "Storage Account currently allowing public access to all blobs or containers, which need to be disabled" { +storage_account_public_access_disabled_err = "Storage Account currently allowing public access to all blobs or containers" { azure_issue["storage_secure"] } storage_account_public_access_disabled_metadata := { - "Policy Code": "PR-AZR-0069-TRF", + "Policy Code": "PR-AZR-0123-TRF", "Type": "IaC", "Product": "AZR", "Language": "Terraform", - "Policy Title": "Storage Account should not allow public access to all blobs or containers", + "Policy Title": "Ensure that Storage Account should not allow public access to all blobs or containers", "Policy Description": "This policy will identify which Storage Account has public access not disabled for all blobs or containers and alert", "Resource Type": "azurerm_storage_account", "Policy Help URL": "", - "Resource Help URL": "https://docs.microsoft.com/en-us/azure/templates/azurerm_storage_account" + "Resource Help URL": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account" } From 3b9c3c8453e734ba3a9ca23cbfe542799f599e56 Mon Sep 17 00:00:00 2001 From: r4redu Date: Tue, 10 Aug 2021 03:43:29 -0700 Subject: [PATCH 6/8] verfied and fixed storageblobcontainers.rego --- azure/iac/master-compliance-test.json | 6 +-- azure/iac/storageblobcontainers.rego | 29 +++++++------- azure/terraform/master-compliance-test.json | 10 ++--- azure/terraform/storageblobcontainers.rego | 43 +++++++++++++-------- 4 files changed, 48 insertions(+), 40 deletions(-) diff --git a/azure/iac/master-compliance-test.json b/azure/iac/master-compliance-test.json index 1651bcad..278cfa74 100644 --- a/azure/iac/master-compliance-test.json +++ b/azure/iac/master-compliance-test.json @@ -2868,14 +2868,14 @@ "evals": [ { "id": "PR-AZR-0074-ARM", - "eval": "data.rule.storage_public_access_disabled", - "message": "data.rule.storage_public_access_disabled_err", + "eval": "data.rule.storage_container_public_access_disabled", + "message": "data.rule.storage_container_public_access_disabled_err", "remediationDescription": "Make sure you are following the ARM template guidelines for storage accounts from this URL : https://docs.microsoft.com/en-us/azure/templates/microsoft.storage/2019-06-01/storageaccounts/blobservices/containers", "remediationFunction": "PR_AZR_0074_ARM.py" } ], "severity": "Medium", - "title": "Azure storage account should not allow public access to the blob container", + "title": "Azure storage blob container should not have public access enabled", "description": "'Public access level' allows you to grant anonymous/public read access to a container and the blobs within Azure blob storage. By doing so, you can grant read-only access to these resources without sharing your account key, and without requiring a shared access signature._x005F_x000D_ _x005F_x000D_ This policy identifies blob containers within an Azure storage account that allow anonymous/public access ('CONTAINER' or 'BLOB'). As a best practice, do not allow anonymous/public access to blob containers unless you have a very good reason. Instead, you should consider using a shared access signature token for providing controlled and time-limited access to blob containers.", "tags": [ { diff --git a/azure/iac/storageblobcontainers.rego b/azure/iac/storageblobcontainers.rego index 3ff866ea..506c420d 100644 --- a/azure/iac/storageblobcontainers.rego +++ b/azure/iac/storageblobcontainers.rego @@ -4,57 +4,54 @@ package rule # # PR-AZR-0074-ARM -# PR-AZR-0013-ARM # -default storage_public_access_disabled = null +default storage_container_public_access_disabled = null #https://docs.microsoft.com/en-us/azure/storage/blobs/anonymous-read-access-configure?tabs=portal -azure_attribute_absence["storage_public_access_disabled"] { +azure_attribute_absence["storage_container_public_access_disabled"] { resource := input.resources[_] lower(resource.type) == "microsoft.storage/storageaccounts/blobservices/containers" not resource.properties.publicAccess } -azure_issue["storage_public_access_disabled"] { +azure_issue["storage_container_public_access_disabled"] { resource := input.resources[_] lower(resource.type) == "microsoft.storage/storageaccounts/blobservices/containers" lower(resource.properties.publicAccess) == "container" } -azure_issue["storage_public_access_disabled"] { +azure_issue["storage_container_public_access_disabled"] { resource := input.resources[_] lower(resource.type) == "microsoft.storage/storageaccounts/blobservices/containers" lower(resource.properties.publicAccess) == "blob" } -storage_public_access_disabled { +storage_container_public_access_disabled { lower(input.resources[_].type) == "microsoft.storage/storageaccounts/blobservices/containers" - not azure_attribute_absence["storage_public_access_disabled"] - not azure_issue["storage_public_access_disabled"] + not azure_attribute_absence["storage_container_public_access_disabled"] + not azure_issue["storage_container_public_access_disabled"] } -storage_public_access_disabled = false { +storage_container_public_access_disabled = false { azure_issue["storage_public_access_disabled"] } -storage_public_access_disabled { +storage_container_public_access_disabled { azure_attribute_absence["storage_public_access_disabled"] } -storage_public_access_disabled_err = "Azure storage account currently allowing public access to the blob container" { +storage_container_public_access_disabled_err = "Azure storage account currently allowing public access to the blob container" { azure_issue["storage_public_access_disabled"] -} - -storage_public_access_disabled_err = "Azure storage account blob service property 'publicAccess' is missing from the resource" { +} else = "Azure storage account blob service property 'publicAccess' is missing from the resource" { azure_attribute_absence["storage_public_access_disabled"] } -storage_public_access_disabled_metadata := { +storage_container_public_access_disabled_metadata := { "Policy Code": "PR-AZR-0074-ARM", "Type": "IaC", "Product": "AZR", "Language": "ARM template", - "Policy Title": "Azure storage account should not allow public access to the blob container", + "Policy Title": "Azure storage blob container should not have public access enabled", "Policy Description": "'Public access level' allows you to grant anonymous/public read access to a container and the blobs within Azure blob storage. By doing so, you can grant read-only access to these resources without sharing your account key, and without requiring a shared access signature._x005F_x000D_ _x005F_x000D_ This policy identifies blob containers within an Azure storage account that allow anonymous/public access ('CONTAINER' or 'BLOB'). As a best practice, do not allow anonymous/public access to blob containers unless you have a very good reason. Instead, you should consider using a shared access signature token for providing controlled and time-limited access to blob containers.", "Resource Type": "microsoft.storage/storageaccounts/blobservices/containers", "Policy Help URL": "", diff --git a/azure/terraform/master-compliance-test.json b/azure/terraform/master-compliance-test.json index 8c318684..d9c30c27 100644 --- a/azure/terraform/master-compliance-test.json +++ b/azure/terraform/master-compliance-test.json @@ -1953,15 +1953,15 @@ "rule": "file(storageblobcontainers.rego)", "evals": [ { - "id": "PR-AZR-0013-TRF", - "eval": "data.rule.storage_public_access", - "message": "data.rule.storage_public_access_err", - "remediationDescription": "", + "id": "PR-AZR-0074-TRF", + "eval": "data.rule.storage_container_public_access_disabled", + "message": "data.rule.storage_container_public_access_disabled_err", + "remediationDescription": "In 'azurerm_storage_container' resource, set 'container_access_type = private' or remove the container_access_type property to fix the issue. Visit https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container#container_access_type for details.", "remediationFunction": "" } ], "severity": "Medium", - "title": "Azure Blob container(s) with public access and logging set to less than 180 days (TJX)", + "title": "Azure storage blob container should not have public access enabled", "description": "'Public access level' allows you to grant anonymous/public read access to a container and the blobs within Azure blob storage. By doing so, you can grant read-only access to these resources without sharing your account key, and without requiring a shared access signature._x000D__x000D_This policy identifies blob containers within an Azure storage account that allow anonymous/public access ('CONTAINER' or 'BLOB') that also have Audit Log Retention set to less than 180 days._x000D__x000D_As a best practice, do not allow anonymous/public access to blob containers unless you have a very good reason. Instead, you should consider using a shared access signature token for providing controlled and time-limited access to blob containers.", "tags": [ { diff --git a/azure/terraform/storageblobcontainers.rego b/azure/terraform/storageblobcontainers.rego index 31c7f348..0ff9b0b7 100644 --- a/azure/terraform/storageblobcontainers.rego +++ b/azure/terraform/storageblobcontainers.rego @@ -1,41 +1,52 @@ package rule # https://docs.microsoft.com/en-us/azure/templates/microsoft.storage/2019-06-01/storageaccounts/blobservices/containers - +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container # # PR-AZR-0074-TRF -# PR-AZR-0013-TRF # -default storage_public_access = null +default storage_container_public_access_disabled = null + +# Defaults to private +azure_attribute_absence["storage_container_public_access_disabled"] { + resource := input.resources[_] + lower(resource.type) == "azurerm_storage_container" + not resource.properties.container_access_type +} -azure_issue["storage_public_access"] { +azure_issue["storage_container_public_access_disabled"] { resource := input.resources[_] - lower(resource.type) == "azurerm_storage_account" - resource.properties.allow_blob_public_access + lower(resource.type) == "azurerm_storage_container" + lower(resource.properties.container_access_type) != "private" +} + +storage_container_public_access_disabled { + lower(input.resources[_].type) == "azurerm_storage_container" + not azure_attribute_absence["storage_container_public_access_disabled"] + not azure_issue["storage_container_public_access_disabled"] } -storage_public_access { - lower(input.resources[_].type) == "azurerm_storage_account" - not azure_issue["storage_public_access"] +storage_container_public_access_disabled { + azure_attribute_absence["storage_container_public_access_disabled"] } -storage_public_access = false { - azure_issue["storage_public_access"] +storage_container_public_access_disabled = false { + azure_issue["storage_container_public_access_disabled"] } -storage_public_access_err = "Azure storage accounts has blob containers with public access" { - azure_issue["storage_public_access"] +storage_container_public_access_disabled_err = "Azure storage accounts has blob containers with public access" { + azure_issue["storage_container_public_access_disabled"] } -storage_public_access_metadata := { +storage_container_public_access_disabled_metadata := { "Policy Code": "PR-AZR-0074-TRF", "Type": "IaC", "Product": "AZR", "Language": "Terraform", - "Policy Title": "Azure storage accounts has blob container(s) with public access", + "Policy Title": "Azure storage blob container should not have public access enabled", "Policy Description": "'Public access level' allows you to grant anonymous/public read access to a container and the blobs within Azure blob storage. By doing so, you can grant read-only access to these resources without sharing your account key, and without requiring a shared access signature._x005F_x000D_ _x005F_x000D_ This policy identifies blob containers within an Azure storage account that allow anonymous/public access ('CONTAINER' or 'BLOB'). As a best practice, do not allow anonymous/public access to blob containers unless you have a very good reason. Instead, you should consider using a shared access signature token for providing controlled and time-limited access to blob containers.", "Resource Type": "azurerm_storage_account", "Policy Help URL": "", - "Resource Help URL": "https://docs.microsoft.com/en-us/azure/templates/microsoft.storage/2019-06-01/storageaccounts/blobservices/containers" + "Resource Help URL": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container" } From a2d35a40e23529a162f5c9c51636654ea9c05e1d Mon Sep 17 00:00:00 2001 From: r4redu Date: Tue, 10 Aug 2021 04:24:11 -0700 Subject: [PATCH 7/8] verified vnetsubnets.rego --- azure/terraform/master-compliance-test.json | 8 +++--- azure/terraform/vnetsubnets.rego | 31 +++++++++++++-------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/azure/terraform/master-compliance-test.json b/azure/terraform/master-compliance-test.json index d9c30c27..7206581a 100644 --- a/azure/terraform/master-compliance-test.json +++ b/azure/terraform/master-compliance-test.json @@ -1982,16 +1982,16 @@ "rule": "file(vnetsubnets.rego)", "evals": [ { - "id": "PR-AZR-0067-TRF", + "id": "PR-AZR-0066-TRF", "eval": "data.rule.vnet_subnet_nsg", "message": "data.rule.vnet_subnet_nsg_err", - "remediationDescription": "", + "remediationDescription": "In 'azurerm_subnet_network_security_group_association' resource, make sure both 'subnet_id' and 'network_security_group_id' property exist and both has id from 'azurerm_subnet' and 'azurerm_network_security_group' resource respectively to fix the issue. Visit https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet_network_security_group_association#network_security_group_id for details.", "remediationFunction": "" } ], "severity": "Medium", - "title": "Azure Virtual Network subnet is not configured with a Network Security Group (TJX)", - "description": "** MODIFICATION OF DEFAULT RULE - GatewaySubnets Excluded as of 08 APR 2019, GatewaySubnets do not support the application of NSGs **_x000D__x000D_** AzureFirewallSubnet Excluded as of 08 APR 2019 **_x000D__x000D_This policy identifies Azure Virtual Network (VNet) subnets that are not associated with a Network Security Group (NSG). While binding an NSG to a network interface of a Virtual Machine (VM) enables fine-grained control to the VM, associating a NSG to a subnet enables better control over network traffic to all resources within a subnet. As a best practice, associate an NSG with a subnet so that you can protect your VMs on a subnet-level._x000D__x000D_For more information, see https://blogs.msdn.microsoft.com/igorpag/2016/05/14/azure-network-security-groups-nsg-best-practices-and-lessons-learned/", + "title": "Azure Virtual Network subnet should be configured with Network Security Group", + "description": "This policy identifies Azure Virtual Network (VNet) subnets that are not associated with a Network Security Group (NSG). While binding an NSG to a network interface of a Virtual Machine (VM) enables fine-grained control to the VM, associating a NSG to a subnet enables better control over network traffic to all resources within a subnet. As a best practice, associate an NSG with a subnet so that you can protect your VMs on a subnet-level._x005F_x000D_ _x005F_x000D_ For more information, see https://blogs.msdn.microsoft.com/igorpag/2016/05/14/azure-network-security-groups-nsg-best-practices-and-lessons-learned/", "tags": [ { "cloud": "git", diff --git a/azure/terraform/vnetsubnets.rego b/azure/terraform/vnetsubnets.rego index aa78f1bc..39693746 100644 --- a/azure/terraform/vnetsubnets.rego +++ b/azure/terraform/vnetsubnets.rego @@ -1,10 +1,9 @@ package rule # https://docs.microsoft.com/en-us/azure/templates/azurerm_subnet - +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet_network_security_group_association # # PR-AZR-0066-TRF -# PR-AZR-0067-TRF # default vnet_subnet_nsg = null @@ -21,31 +20,39 @@ azure_issue["vnet_subnet_nsg"] { lower(resource.type) == "azurerm_subnet" count([c | r := input.resources[_]; r.type == "azurerm_subnet_network_security_group_association"; - re_match(concat("", ["^.*\\.", resource.name, "\\..*$"]), r.properties.subnet_id); + re_match(concat("", ["^.*\\.", resource.name, "\\..*$"]), r.properties.subnet_id); #matching is not wokring as expected due tf veriable reference in json. eventually we should match with resource.id instead of resource.name as per document but the id will only available from tf output file. it will be impossible to get id during compile time. + c := 1]) == 0 + true == false # workaround for inconsistent resource naming +} + +azure_issue["vnet_subnet_nsg"] { + resource := input.resources[_] + lower(resource.type) == "azurerm_network_security_group" + count([c | r := input.resources[_]; + r.type == "azurerm_subnet_network_security_group_association"; + re_match(concat("", ["^.*\\.", resource.name, "\\..*$"]), r.properties.network_security_group_id ); #matching is not wokring as expected due tf veriable reference in json. eventually we should match with resource.id instead of resource.name as per document but the id will only available from tf output file. it will be impossible to get id during compile time. c := 1]) == 0 true == false # workaround for inconsistent resource naming } vnet_subnet_nsg { lower(input.resources[_].type) == "azurerm_subnet" - not azure_issue["vnet_subnet_nsg"] not azure_attribute_absence["vnet_subnet_nsg"] -} - -vnet_subnet_nsg = false { - azure_issue["vnet_subnet_nsg"] + not azure_issue["vnet_subnet_nsg"] } vnet_subnet_nsg = false { azure_attribute_absence["vnet_subnet_nsg"] } -vnet_subnet_nsg_err = "Azure Virtual Network subnet is not configured with a Network Security Group" { +vnet_subnet_nsg = false { azure_issue["vnet_subnet_nsg"] } -vnet_subnet_nsg_miss_err = "Azure Virtual Network subnet is not configured with a Network Security Group" { +vnet_subnet_nsg_err = "azurerm_subnet_network_security_group_association property 'subnet_id' and 'network_security_group_id' both need to be exist. one or both are missing from the resource." { azure_attribute_absence["vnet_subnet_nsg"] +} else = "Azure Virtual Network subnet is not configured with a Network Security Group" { + azure_issue["vnet_subnet_nsg"] } vnet_subnet_nsg_metadata := { @@ -53,9 +60,9 @@ vnet_subnet_nsg_metadata := { "Type": "IaC", "Product": "AZR", "Language": "Terraform", - "Policy Title": "Azure Virtual Network subnet is not configured with a Network Security Group", + "Policy Title": "Azure Virtual Network subnet should be configured with Network Security Group", "Policy Description": "This policy identifies Azure Virtual Network (VNet) subnets that are not associated with a Network Security Group (NSG). While binding an NSG to a network interface of a Virtual Machine (VM) enables fine-grained control to the VM, associating a NSG to a subnet enables better control over network traffic to all resources within a subnet. As a best practice, associate an NSG with a subnet so that you can protect your VMs on a subnet-level._x005F_x000D_ _x005F_x000D_ For more information, see https://blogs.msdn.microsoft.com/igorpag/2016/05/14/azure-network-security-groups-nsg-best-practices-and-lessons-learned/", "Resource Type": "azurerm_subnet", "Policy Help URL": "", - "Resource Help URL": "https://docs.microsoft.com/en-us/azure/templates/azurerm_subnet" + "Resource Help URL": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet_network_security_group_association" } From d6436bf9e184cfc94af2329a998cb7329d3f4974 Mon Sep 17 00:00:00 2001 From: r4redu Date: Wed, 11 Aug 2021 02:36:17 -0700 Subject: [PATCH 8/8] https://github.com/prancer-io/prancer-compliance-test/issues/189 --- azure/terraform/vnetsubnets.rego | 54 +++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/azure/terraform/vnetsubnets.rego b/azure/terraform/vnetsubnets.rego index 39693746..0bca46f0 100644 --- a/azure/terraform/vnetsubnets.rego +++ b/azure/terraform/vnetsubnets.rego @@ -8,31 +8,55 @@ package rule default vnet_subnet_nsg = null +#azure_attribute_absence["vnet_subnet_nsg"] { +# resource := input.resources[_] +# lower(resource.type) == "azurerm_subnet" +# count([c | input.resources[_].type == "azurerm_subnet_network_security_group_association"; +# c := 1]) == 0 +#} + +#azure_issue["vnet_subnet_nsg"] { +# resource := input.resources[_] +# lower(resource.type) == "azurerm_subnet" +# count([c | r := input.resources[_]; +# r.type == "azurerm_subnet_network_security_group_association"; +# re_match(concat("", ["^.*\\.", resource.name, "\\..*$"]), r.properties.subnet_id); #matching is not wokring as expected due tf veriable reference in json. eventually we should match with resource.id instead of resource.name as per document but the id will only available from tf output file. it will be impossible to get id during compile time. +# c := 1]) == 0 +# true == false # workaround for inconsistent resource naming +#} + +#azure_issue["vnet_subnet_nsg"] { +# resource := input.resources[_] +# lower(resource.type) == "azurerm_network_security_group" +# count([c | r := input.resources[_]; +# r.type == "azurerm_subnet_network_security_group_association"; +# re_match(concat("", ["^.*\\.", resource.name, "\\..*$"]), r.properties.network_security_group_id ); #matching is not wokring as expected due tf veriable reference in json. eventually we should match with resource.id instead of resource.name as per document but the id will only available from tf output file. it will be impossible to get id during compile time. +# c := 1]) == 0 +# true == false # workaround for inconsistent resource naming +#} + +azure_attribute_absence["vnet_subnet_nsg"] { + resource := input.resources[_] + lower(resource.type) == "azurerm_subnet_network_security_group_association" + not resource.subnet_id +} + azure_attribute_absence["vnet_subnet_nsg"] { resource := input.resources[_] - lower(resource.type) == "azurerm_subnet" - count([c | input.resources[_].type == "azurerm_subnet_network_security_group_association"; - c := 1]) == 0 + lower(resource.type) == "azurerm_subnet_network_security_group_association" + not resource.network_security_group_id } azure_issue["vnet_subnet_nsg"] { resource := input.resources[_] - lower(resource.type) == "azurerm_subnet" - count([c | r := input.resources[_]; - r.type == "azurerm_subnet_network_security_group_association"; - re_match(concat("", ["^.*\\.", resource.name, "\\..*$"]), r.properties.subnet_id); #matching is not wokring as expected due tf veriable reference in json. eventually we should match with resource.id instead of resource.name as per document but the id will only available from tf output file. it will be impossible to get id during compile time. - c := 1]) == 0 - true == false # workaround for inconsistent resource naming + lower(resource.type) == "azurerm_subnet_network_security_group_association" + count(resource.subnet_id) == 0 } azure_issue["vnet_subnet_nsg"] { resource := input.resources[_] - lower(resource.type) == "azurerm_network_security_group" - count([c | r := input.resources[_]; - r.type == "azurerm_subnet_network_security_group_association"; - re_match(concat("", ["^.*\\.", resource.name, "\\..*$"]), r.properties.network_security_group_id ); #matching is not wokring as expected due tf veriable reference in json. eventually we should match with resource.id instead of resource.name as per document but the id will only available from tf output file. it will be impossible to get id during compile time. - c := 1]) == 0 - true == false # workaround for inconsistent resource naming + lower(resource.type) == "azurerm_subnet_network_security_group_association" + count(resource.network_security_group_id) == 0 } vnet_subnet_nsg {