From 9668e62967e024770eddb14829a663db6ff438d0 Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Wed, 21 Aug 2024 13:12:41 +0600 Subject: [PATCH] test: add functional tests Signed-off-by: Nikita Pivkin --- avd_docs/azure/compute/AVD-AZU-0037/docs.md | 3 +- avd_docs/azure/database/AVD-AZU-0029/docs.md | 3 +- .../compute/no_secrets_in_custom_data.go | 3 +- .../compute/no_secrets_in_custom_data.rego | 44 + .../compute/no_secrets_in_custom_data_test.go | 71 -- .../no_secrets_in_custom_data_test.rego | 20 + .../azure/database/no_public_access.rego | 4 +- .../azure/database/no_public_access_test.rego | 10 +- .../database/no_public_firewall_access.go | 3 +- .../database/no_public_firewall_access.rego | 54 ++ .../no_public_firewall_access_test.go | 230 ----- .../no_public_firewall_access_test.rego | 36 + .../azure/database/secure_tls_policy.rego | 15 +- .../database/secure_tls_policy_test.rego | 6 +- test/rego/azure_compute_test.go | 107 +++ test/rego/azure_database_test.go | 783 ++++++++++++++++++ test/rego/rego_checks_test.go | 8 +- 17 files changed, 1081 insertions(+), 319 deletions(-) create mode 100644 checks/cloud/azure/compute/no_secrets_in_custom_data.rego delete mode 100644 checks/cloud/azure/compute/no_secrets_in_custom_data_test.go create mode 100644 checks/cloud/azure/compute/no_secrets_in_custom_data_test.rego create mode 100644 checks/cloud/azure/database/no_public_firewall_access.rego delete mode 100644 checks/cloud/azure/database/no_public_firewall_access_test.go create mode 100644 checks/cloud/azure/database/no_public_firewall_access_test.rego create mode 100644 test/rego/azure_compute_test.go create mode 100644 test/rego/azure_database_test.go diff --git a/avd_docs/azure/compute/AVD-AZU-0037/docs.md b/avd_docs/azure/compute/AVD-AZU-0037/docs.md index d2f53e5b..787169d6 100644 --- a/avd_docs/azure/compute/AVD-AZU-0037/docs.md +++ b/avd_docs/azure/compute/AVD-AZU-0037/docs.md @@ -1,8 +1,9 @@ When creating Azure Virtual Machines, custom_data is used to pass start up information into the EC2 instance. This custom_dat must not contain access key credentials. + ### Impact -Sensitive credentials in custom_data can be leaked + {{ remediationActions }} diff --git a/avd_docs/azure/database/AVD-AZU-0029/docs.md b/avd_docs/azure/database/AVD-AZU-0029/docs.md index 0bc32bc4..7bce75cc 100644 --- a/avd_docs/azure/database/AVD-AZU-0029/docs.md +++ b/avd_docs/azure/database/AVD-AZU-0029/docs.md @@ -1,8 +1,9 @@ Azure services can be allowed access through the firewall using a start and end IP address of 0.0.0.0. No other end ip address should be combined with a start of 0.0.0.0 + ### Impact -Publicly accessible databases could lead to compromised data + {{ remediationActions }} diff --git a/checks/cloud/azure/compute/no_secrets_in_custom_data.go b/checks/cloud/azure/compute/no_secrets_in_custom_data.go index 505dacec..f0580ffc 100755 --- a/checks/cloud/azure/compute/no_secrets_in_custom_data.go +++ b/checks/cloud/azure/compute/no_secrets_in_custom_data.go @@ -28,7 +28,8 @@ var CheckNoSecretsInCustomData = rules.Register( Links: terraformNoSecretsInCustomDataLinks, RemediationMarkdown: terraformNoSecretsInCustomDataRemediationMarkdown, }, - Severity: severity.Medium, + Severity: severity.Medium, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, vm := range s.Azure.Compute.LinuxVirtualMachines { diff --git a/checks/cloud/azure/compute/no_secrets_in_custom_data.rego b/checks/cloud/azure/compute/no_secrets_in_custom_data.rego new file mode 100644 index 00000000..49f4eb69 --- /dev/null +++ b/checks/cloud/azure/compute/no_secrets_in_custom_data.rego @@ -0,0 +1,44 @@ +# METADATA +# title: Ensure that no sensitive credentials are exposed in VM custom_data +# description: | +# When creating Azure Virtual Machines, custom_data is used to pass start up information into the EC2 instance. This custom_dat must not contain access key credentials. +# scope: package +# schemas: +# - input: schema["cloud"] +# custom: +# id: AVD-AZU-0037 +# avd_id: AVD-AZU-0037 +# provider: azure +# service: compute +# severity: MEDIUM +# short_code: no-secrets-in-custom-data +# recommended_action: Don't use sensitive credentials in the VM custom_data +# input: +# selector: +# - type: cloud +# subtypes: +# - service: compute +# provider: azure +# terraform: +# links: +# - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine#custom_data +# good_examples: checks/cloud/azure/compute/no_secrets_in_custom_data.tf.go +# bad_examples: checks/cloud/azure/compute/no_secrets_in_custom_data.tf.go +package builtin.azure.compute.azure0037 + +import rego.v1 + +deny contains res if { + vms := array.concat( + object.get(input.azure.compute, "linuxvirtualmachines", []), + object.get(input.azure.compute, "windowsvirtualmachines", []), + ) + + some vm in vms + scan_result := squealer.scan_string(vm.virtualmachine.customdata.value) + scan_result.transgressionFound + res := result.new( + "Virtual machine includes secret(s) in custom data.", + vm.virtualmachine, + ) +} diff --git a/checks/cloud/azure/compute/no_secrets_in_custom_data_test.go b/checks/cloud/azure/compute/no_secrets_in_custom_data_test.go deleted file mode 100644 index 3af093e3..00000000 --- a/checks/cloud/azure/compute/no_secrets_in_custom_data_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package compute - -import ( - "testing" - - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - - "github.com/aquasecurity/trivy/pkg/iac/state" - - "github.com/aquasecurity/trivy/pkg/iac/providers/azure/compute" - "github.com/aquasecurity/trivy/pkg/iac/scan" - - "github.com/stretchr/testify/assert" -) - -func TestCheckNoSecretsInCustomData(t *testing.T) { - tests := []struct { - name string - input compute.Compute - expected bool - }{ - { - name: "Secrets in custom data", - input: compute.Compute{ - LinuxVirtualMachines: []compute.LinuxVirtualMachine{ - { - Metadata: trivyTypes.NewTestMetadata(), - VirtualMachine: compute.VirtualMachine{ - Metadata: trivyTypes.NewTestMetadata(), - CustomData: trivyTypes.String(`export DATABASE_PASSWORD=\"SomeSortOfPassword\"`, trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - expected: true, - }, - { - name: "No secrets in custom data", - input: compute.Compute{ - LinuxVirtualMachines: []compute.LinuxVirtualMachine{ - { - Metadata: trivyTypes.NewTestMetadata(), - VirtualMachine: compute.VirtualMachine{ - Metadata: trivyTypes.NewTestMetadata(), - CustomData: trivyTypes.String(`export GREETING="Hello there"`, trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - expected: false, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.Azure.Compute = test.input - results := CheckNoSecretsInCustomData.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckNoSecretsInCustomData.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/azure/compute/no_secrets_in_custom_data_test.rego b/checks/cloud/azure/compute/no_secrets_in_custom_data_test.rego new file mode 100644 index 00000000..4f49b483 --- /dev/null +++ b/checks/cloud/azure/compute/no_secrets_in_custom_data_test.rego @@ -0,0 +1,20 @@ +package builtin.azure.compute.azure0037_test + +import rego.v1 + +import data.builtin.azure.compute.azure0037 as check +import data.lib.test + +test_deny_secrets_in_custom_data if { + inp := {"azure": {"compute": {"linuxvirtualmachines": [{"virtualmachine": {"customdata": {"value": `export DATABASE_PASSWORD=\"SomeSortOfPassword\"`}}}]}}} + + res := check.deny with input as inp + count(res) == 1 +} + +test_allow_no_secrets_in_custom_data if { + inp := {"azure": {"compute": {"linuxvirtualmachines": [{"virtualmachine": {"customdata": {"value": `export GREETING="Hello there"`}}}]}}} + + res := check.deny with input as inp + count(res) == 0 +} diff --git a/checks/cloud/azure/database/no_public_access.rego b/checks/cloud/azure/database/no_public_access.rego index 2102ae7e..339d4b97 100644 --- a/checks/cloud/azure/database/no_public_access.rego +++ b/checks/cloud/azure/database/no_public_access.rego @@ -37,8 +37,8 @@ deny contains res if { is_public_access_enabled(server) res := result.new( "Database server does not have public access enabled.", - object.get(server, "publicnetworkaccessenabled", server), + object.get(server, "enablepublicnetworkaccess", server), ) } -is_public_access_enabled(server) := server.publicnetworkaccessenabled.value == true +is_public_access_enabled(server) := server.enablepublicnetworkaccess.value == true diff --git a/checks/cloud/azure/database/no_public_access_test.rego b/checks/cloud/azure/database/no_public_access_test.rego index 37a2c876..a8002d39 100644 --- a/checks/cloud/azure/database/no_public_access_test.rego +++ b/checks/cloud/azure/database/no_public_access_test.rego @@ -27,13 +27,13 @@ test_deny_postgresql_server_public_access_enabled if { test_allow_servers_public_access_disabled if { inp := {"azure": {"database": { - "mysqlservers": [{"server": {"publicnetworkaccessenabled": {"value": false}}}], - "mssqlservers": [{"server": {"publicnetworkaccessenabled": {"value": false}}}], - "mariadbservers": [{"server": {"publicnetworkaccessenabled": {"value": false}}}], - "postgresqlservers": [{"server": {"publicnetworkaccessenabled": {"value": false}}}], + "mysqlservers": [{"server": {"enablepublicnetworkaccess": {"value": false}}}], + "mssqlservers": [{"server": {"enablepublicnetworkaccess": {"value": false}}}], + "mariadbservers": [{"server": {"enablepublicnetworkaccess": {"value": false}}}], + "postgresqlservers": [{"server": {"enablepublicnetworkaccess": {"value": false}}}], }}} res := check.deny with input as inp count(res) == 0 } -build_input(db_type, public_access) := {"azure": {"database": {db_type: [{"server": {"publicnetworkaccessenabled": {"value": public_access}}}]}}} +build_input(db_type, public_access) := {"azure": {"database": {db_type: [{"server": {"enablepublicnetworkaccess": {"value": public_access}}}]}}} diff --git a/checks/cloud/azure/database/no_public_firewall_access.go b/checks/cloud/azure/database/no_public_firewall_access.go index 1043665e..7373be72 100755 --- a/checks/cloud/azure/database/no_public_firewall_access.go +++ b/checks/cloud/azure/database/no_public_firewall_access.go @@ -29,7 +29,8 @@ var CheckNoPublicFirewallAccess = rules.Register( Links: terraformNoPublicFirewallAccessLinks, RemediationMarkdown: terraformNoPublicFirewallAccessRemediationMarkdown, }, - Severity: severity.High, + Severity: severity.High, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, server := range s.Azure.Database.MariaDBServers { diff --git a/checks/cloud/azure/database/no_public_firewall_access.rego b/checks/cloud/azure/database/no_public_firewall_access.rego new file mode 100644 index 00000000..bbdb5571 --- /dev/null +++ b/checks/cloud/azure/database/no_public_firewall_access.rego @@ -0,0 +1,54 @@ +# METADATA +# title: Ensure database firewalls do not permit public access +# description: | +# Azure services can be allowed access through the firewall using a start and end IP address of 0.0.0.0. No other end ip address should be combined with a start of 0.0.0.0 +# scope: package +# schemas: +# - input: schema["cloud"] +# related_resources: +# - https://docs.microsoft.com/en-us/rest/api/sql/2021-02-01-preview/firewall-rules/create-or-update +# custom: +# id: AVD-AZU-0029 +# avd_id: AVD-AZU-0029 +# provider: azure +# service: database +# severity: HIGH +# short_code: no-public-firewall-access +# recommended_action: Don't use wide ip ranges for the sql firewall +# input: +# selector: +# - type: cloud +# subtypes: +# - service: database +# provider: azure +# terraform: +# links: +# - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/sql_firewall_rule#end_ip_address +# good_examples: checks/cloud/azure/database/no_public_firewall_access.tf.go +# bad_examples: checks/cloud/azure/database/no_public_firewall_access.tf.go +package builtin.azure.database.azure0029 + +import rego.v1 + +import data.lib.azure.database + +deny contains res if { + some server in database.all_servers + some rule in server.firewallrules + not allowing_azure_services(rule) + rule.startip.value != rule.endip.value + is_public_rule(rule) + res := result.new( + "Firewall rule allows public internet access to a database server.", + rule, + ) +} + +is_public_rule(rule) if cidr.is_public(rule.startip.value) + +is_public_rule(rule) if cidr.is_public(rule.endip.value) + +allowing_azure_services(rule) if { + rule.startip.value == "0.0.0.0" + rule.endip.value == "0.0.0.0" +} diff --git a/checks/cloud/azure/database/no_public_firewall_access_test.go b/checks/cloud/azure/database/no_public_firewall_access_test.go deleted file mode 100644 index 8b419d6c..00000000 --- a/checks/cloud/azure/database/no_public_firewall_access_test.go +++ /dev/null @@ -1,230 +0,0 @@ -package database - -import ( - "testing" - - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - - "github.com/aquasecurity/trivy/pkg/iac/state" - - "github.com/aquasecurity/trivy/pkg/iac/providers/azure/database" - "github.com/aquasecurity/trivy/pkg/iac/scan" - - "github.com/stretchr/testify/assert" -) - -func TestCheckNoPublicFirewallAccess(t *testing.T) { - tests := []struct { - name string - input database.Database - expected bool - }{ - { - name: "MySQL server firewall allows public internet access", - input: database.Database{ - MySQLServers: []database.MySQLServer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Server: database.Server{ - Metadata: trivyTypes.NewTestMetadata(), - FirewallRules: []database.FirewallRule{ - { - Metadata: trivyTypes.NewTestMetadata(), - StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - EndIP: trivyTypes.String("255.255.255.255", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "MySQL server firewall allows single public internet access", - input: database.Database{ - MySQLServers: []database.MySQLServer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Server: database.Server{ - Metadata: trivyTypes.NewTestMetadata(), - FirewallRules: []database.FirewallRule{ - { - Metadata: trivyTypes.NewTestMetadata(), - StartIP: trivyTypes.String("8.8.8.8", trivyTypes.NewTestMetadata()), - EndIP: trivyTypes.String("8.8.8.8", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - }, - expected: false, - }, - { - name: "MS SQL server firewall allows public internet access", - input: database.Database{ - MSSQLServers: []database.MSSQLServer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Server: database.Server{ - Metadata: trivyTypes.NewTestMetadata(), - FirewallRules: []database.FirewallRule{ - { - Metadata: trivyTypes.NewTestMetadata(), - StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - EndIP: trivyTypes.String("255.255.255.255", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "PostgreSQL server firewall allows public internet access", - input: database.Database{ - PostgreSQLServers: []database.PostgreSQLServer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Server: database.Server{ - Metadata: trivyTypes.NewTestMetadata(), - FirewallRules: []database.FirewallRule{ - { - Metadata: trivyTypes.NewTestMetadata(), - StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - EndIP: trivyTypes.String("255.255.255.255", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "MariaDB server firewall allows public internet access", - input: database.Database{ - MariaDBServers: []database.MariaDBServer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Server: database.Server{ - Metadata: trivyTypes.NewTestMetadata(), - FirewallRules: []database.FirewallRule{ - { - Metadata: trivyTypes.NewTestMetadata(), - StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - EndIP: trivyTypes.String("255.255.255.255", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "MySQL server firewall allows access to Azure services", - input: database.Database{ - MySQLServers: []database.MySQLServer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Server: database.Server{ - Metadata: trivyTypes.NewTestMetadata(), - FirewallRules: []database.FirewallRule{ - { - Metadata: trivyTypes.NewTestMetadata(), - StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - EndIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - }, - expected: false, - }, - { - name: "MS SQL server firewall allows access to Azure services", - input: database.Database{ - MSSQLServers: []database.MSSQLServer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Server: database.Server{ - Metadata: trivyTypes.NewTestMetadata(), - FirewallRules: []database.FirewallRule{ - { - Metadata: trivyTypes.NewTestMetadata(), - StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - EndIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - }, - expected: false, - }, - { - name: "PostgreSQL server firewall allows access to Azure services", - input: database.Database{ - PostgreSQLServers: []database.PostgreSQLServer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Server: database.Server{ - Metadata: trivyTypes.NewTestMetadata(), - FirewallRules: []database.FirewallRule{ - { - Metadata: trivyTypes.NewTestMetadata(), - StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - EndIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - }, - expected: false, - }, - { - name: "MariaDB server firewall allows access to Azure services", - input: database.Database{ - MariaDBServers: []database.MariaDBServer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Server: database.Server{ - Metadata: trivyTypes.NewTestMetadata(), - FirewallRules: []database.FirewallRule{ - { - Metadata: trivyTypes.NewTestMetadata(), - StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - EndIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - }, - expected: false, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.Azure.Database = test.input - results := CheckNoPublicFirewallAccess.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckNoPublicFirewallAccess.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/azure/database/no_public_firewall_access_test.rego b/checks/cloud/azure/database/no_public_firewall_access_test.rego new file mode 100644 index 00000000..ee18984a --- /dev/null +++ b/checks/cloud/azure/database/no_public_firewall_access_test.rego @@ -0,0 +1,36 @@ +package builtin.azure.database.azure0029_test + +import rego.v1 + +import data.builtin.azure.database.azure0029 as check +import data.lib.test + +test_deny_mysql_server_allow_public_access if { + inp := {"azure": {"database": {"mysqlservers": [{"server": {"firewallrules": [{ + "startip": {"value": "0.0.0.0"}, + "endip": {"value": "255.255.255.255"}, + }]}}]}}} + + res := check.deny with input as inp + count(res) == 1 +} + +test_allow_mysql_server_allow_single_public_access if { + inp := {"azure": {"database": {"mysqlservers": [{"server": {"firewallrules": [{ + "startip": {"value": "8.8.8.8"}, + "endip": {"value": "8.8.8.8"}, + }]}}]}}} + + res := check.deny with input as inp + count(res) == 0 +} + +test_allow_mysql_server_allow_access_to_azure_services if { + inp := {"azure": {"database": {"mysqlservers": [{"server": {"firewallrules": [{ + "startip": {"value": "0.0.0.0"}, + "endip": {"value": "0.0.0.0"}, + }]}}]}}} + + res := check.deny with input as inp + count(res) == 0 +} diff --git a/checks/cloud/azure/database/secure_tls_policy.rego b/checks/cloud/azure/database/secure_tls_policy.rego index e91f5275..6ce43696 100644 --- a/checks/cloud/azure/database/secure_tls_policy.rego +++ b/checks/cloud/azure/database/secure_tls_policy.rego @@ -34,8 +34,10 @@ import data.lib.azure.database recommended_tls_version := "TLS1_2" +recommended_mssql_tls_version := "1.2" + deny contains res if { - some server in database.servers(["mssqlservers", "mysqlservers", "postgresqlservers"]) + some server in database.servers(["mysqlservers", "postgresqlservers"]) not is_recommended_tls(server) res := result.new( "Database server does not require a secure TLS version.", @@ -43,4 +45,15 @@ deny contains res if { ) } +deny contains res if { + some server in database.servers(["mssqlservers"]) + not is_recommended_mssql_tls(server) + res := result.new( + "Database server does not require a secure TLS version.", + object.get(server, "minimumtlsversion", server), + ) +} + is_recommended_tls(server) := server.minimumtlsversion.value == recommended_tls_version + +is_recommended_mssql_tls(server) := server.minimumtlsversion.value == recommended_mssql_tls_version diff --git a/checks/cloud/azure/database/secure_tls_policy_test.rego b/checks/cloud/azure/database/secure_tls_policy_test.rego index 56d0c0f7..cd5efb81 100644 --- a/checks/cloud/azure/database/secure_tls_policy_test.rego +++ b/checks/cloud/azure/database/secure_tls_policy_test.rego @@ -13,14 +13,14 @@ test_deny_msql_server_minimum_tls_version_is_1_0 if { } test_deny_mysql_server_minimum_tls_version_is_1_0 if { - inp := {"azure": {"database": {"mysqlservers": [build_server("1.0")]}}} + inp := {"azure": {"database": {"mysqlservers": [build_server("TLS1_0")]}}} res := check.deny with input as inp count(res) == 1 } test_deny_postgresql_server_minimum_tls_version_is_1_0 if { - inp := {"azure": {"database": {"postgresqlservers": [build_server("1.0")]}}} + inp := {"azure": {"database": {"postgresqlservers": [build_server("TLS1_0")]}}} res := check.deny with input as inp count(res) == 1 @@ -28,7 +28,7 @@ test_deny_postgresql_server_minimum_tls_version_is_1_0 if { test_allow_servers_with_minimum_tls_version_1_2 if { inp := {"azure": {"database": { - "mssqlservers": [build_server(check.recommended_tls_version)], + "mssqlservers": [build_server(check.recommended_mssql_tls_version)], "mysqlservers": [build_server(check.recommended_tls_version)], "postgresqlservers": [build_server(check.recommended_tls_version)], }}} diff --git a/test/rego/azure_compute_test.go b/test/rego/azure_compute_test.go new file mode 100644 index 00000000..2d71e68d --- /dev/null +++ b/test/rego/azure_compute_test.go @@ -0,0 +1,107 @@ +package test + +import ( + "github.com/aquasecurity/trivy/pkg/iac/providers/azure" + "github.com/aquasecurity/trivy/pkg/iac/providers/azure/compute" + "github.com/aquasecurity/trivy/pkg/iac/state" + trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" +) + +var azureComputeTestCases = testCases{ + "AVD-AZU-0039": { + { + name: "Linux VM password authentication enabled", + input: state.State{Azure: azure.Azure{Compute: compute.Compute{ + LinuxVirtualMachines: []compute.LinuxVirtualMachine{ + { + Metadata: trivyTypes.NewTestMetadata(), + OSProfileLinuxConfig: compute.OSProfileLinuxConfig{ + Metadata: trivyTypes.NewTestMetadata(), + DisablePasswordAuthentication: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "Linux VM password authentication disabled", + input: state.State{Azure: azure.Azure{Compute: compute.Compute{ + LinuxVirtualMachines: []compute.LinuxVirtualMachine{ + { + Metadata: trivyTypes.NewTestMetadata(), + OSProfileLinuxConfig: compute.OSProfileLinuxConfig{ + Metadata: trivyTypes.NewTestMetadata(), + DisablePasswordAuthentication: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0038": { + { + name: "Managed disk encryption disabled", + input: state.State{Azure: azure.Azure{Compute: compute.Compute{ + ManagedDisks: []compute.ManagedDisk{ + { + Metadata: trivyTypes.NewTestMetadata(), + Encryption: compute.Encryption{ + Metadata: trivyTypes.NewTestMetadata(), + Enabled: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "Managed disk encryption enabled", + input: state.State{Azure: azure.Azure{Compute: compute.Compute{ + ManagedDisks: []compute.ManagedDisk{ + { + Metadata: trivyTypes.NewTestMetadata(), + Encryption: compute.Encryption{ + Metadata: trivyTypes.NewTestMetadata(), + Enabled: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0037": { + { + name: "Secrets in custom data", + input: state.State{Azure: azure.Azure{Compute: compute.Compute{ + LinuxVirtualMachines: []compute.LinuxVirtualMachine{ + { + Metadata: trivyTypes.NewTestMetadata(), + VirtualMachine: compute.VirtualMachine{ + Metadata: trivyTypes.NewTestMetadata(), + CustomData: trivyTypes.String(`export DATABASE_PASSWORD=\"SomeSortOfPassword\"`, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "No secrets in custom data", + input: state.State{Azure: azure.Azure{Compute: compute.Compute{ + LinuxVirtualMachines: []compute.LinuxVirtualMachine{ + { + Metadata: trivyTypes.NewTestMetadata(), + VirtualMachine: compute.VirtualMachine{ + Metadata: trivyTypes.NewTestMetadata(), + CustomData: trivyTypes.String(`export GREETING="Hello there"`, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + }, +} diff --git a/test/rego/azure_database_test.go b/test/rego/azure_database_test.go new file mode 100644 index 00000000..743c50a8 --- /dev/null +++ b/test/rego/azure_database_test.go @@ -0,0 +1,783 @@ +package test + +import ( + "github.com/aquasecurity/trivy/pkg/iac/providers/azure" + "github.com/aquasecurity/trivy/pkg/iac/providers/azure/database" + "github.com/aquasecurity/trivy/pkg/iac/state" + trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" +) + +var azureDatabaseTestCases = testCases{ + "AVD-AZU-0028": { + { + name: "MS SQL server alerts for SQL injection disabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + SecurityAlertPolicies: []database.SecurityAlertPolicy{ + { + Metadata: trivyTypes.NewTestMetadata(), + DisabledAlerts: []trivyTypes.StringValue{ + trivyTypes.String("Sql_Injection", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MS SQL server all alerts enabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + SecurityAlertPolicies: []database.SecurityAlertPolicy{ + { + Metadata: trivyTypes.NewTestMetadata(), + DisabledAlerts: []trivyTypes.StringValue{}, + }, + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0027": { + { + name: "MS SQL server extended audit policy not configured", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + ExtendedAuditingPolicies: []database.ExtendedAuditingPolicy{}, + }, + }, + }}}, + expected: true, + }, + { + name: "MS SQL server extended audit policy configured", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + ExtendedAuditingPolicies: []database.ExtendedAuditingPolicy{ + { + Metadata: trivyTypes.NewTestMetadata(), + RetentionInDays: trivyTypes.Int(6, trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0020": { + { + name: "MariaDB server SSL not enforced", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MariaDBServers: []database.MariaDBServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnableSSLEnforcement: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MySQL server SSL not enforced", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MySQLServers: []database.MySQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnableSSLEnforcement: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "PostgreSQL server SSL not enforced", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnableSSLEnforcement: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MariaDB server SSL enforced", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MariaDBServers: []database.MariaDBServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnableSSLEnforcement: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + { + name: "MySQL server SSL enforced", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MySQLServers: []database.MySQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnableSSLEnforcement: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + { + name: "PostgreSQL server SSL enforced", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnableSSLEnforcement: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0022": { + { + name: "MySQL server public access enabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MySQLServers: []database.MySQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnablePublicNetworkAccess: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MariaDB server public access enabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MariaDBServers: []database.MariaDBServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnablePublicNetworkAccess: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MS SQL server public access enabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnablePublicNetworkAccess: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "PostgreSQL server public access enabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnablePublicNetworkAccess: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MySQL server public access disabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MySQLServers: []database.MySQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnablePublicNetworkAccess: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + { + name: "MariaDB server public access disabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MariaDBServers: []database.MariaDBServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnablePublicNetworkAccess: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + { + name: "MS SQL server public access disabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnablePublicNetworkAccess: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + { + name: "PostgreSQL server public access disabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + EnablePublicNetworkAccess: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0029": { + { + name: "MySQL server firewall allows public internet access", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MySQLServers: []database.MySQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + FirewallRules: []database.FirewallRule{ + { + Metadata: trivyTypes.NewTestMetadata(), + StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + EndIP: trivyTypes.String("255.255.255.255", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MySQL server firewall allows single public internet access", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MySQLServers: []database.MySQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + FirewallRules: []database.FirewallRule{ + { + Metadata: trivyTypes.NewTestMetadata(), + StartIP: trivyTypes.String("8.8.8.8", trivyTypes.NewTestMetadata()), + EndIP: trivyTypes.String("8.8.8.8", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }, + }}}, + expected: false, + }, + { + name: "MS SQL server firewall allows public internet access", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + FirewallRules: []database.FirewallRule{ + { + Metadata: trivyTypes.NewTestMetadata(), + StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + EndIP: trivyTypes.String("255.255.255.255", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }, + }}}, + expected: true, + }, + { + name: "PostgreSQL server firewall allows public internet access", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + FirewallRules: []database.FirewallRule{ + { + Metadata: trivyTypes.NewTestMetadata(), + StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + EndIP: trivyTypes.String("255.255.255.255", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MariaDB server firewall allows public internet access", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MariaDBServers: []database.MariaDBServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + FirewallRules: []database.FirewallRule{ + { + Metadata: trivyTypes.NewTestMetadata(), + StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + EndIP: trivyTypes.String("255.255.255.255", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MySQL server firewall allows access to Azure services", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MySQLServers: []database.MySQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + FirewallRules: []database.FirewallRule{ + { + Metadata: trivyTypes.NewTestMetadata(), + StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + EndIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }, + }}}, + expected: false, + }, + { + name: "MS SQL server firewall allows access to Azure services", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + FirewallRules: []database.FirewallRule{ + { + Metadata: trivyTypes.NewTestMetadata(), + StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + EndIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }, + }}}, + expected: false, + }, + { + name: "PostgreSQL server firewall allows access to Azure services", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + FirewallRules: []database.FirewallRule{ + { + Metadata: trivyTypes.NewTestMetadata(), + StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + EndIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }, + }}}, + expected: false, + }, + { + name: "MariaDB server firewall allows access to Azure services", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MariaDBServers: []database.MariaDBServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + FirewallRules: []database.FirewallRule{ + { + Metadata: trivyTypes.NewTestMetadata(), + StartIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + EndIP: trivyTypes.String("0.0.0.0", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0021": { + { + name: "PostgreSQL server connection throttling disabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Config: database.PostgresSQLConfig{ + Metadata: trivyTypes.NewTestMetadata(), + ConnectionThrottling: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "PostgreSQL server connection throttling enabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Config: database.PostgresSQLConfig{ + Metadata: trivyTypes.NewTestMetadata(), + ConnectionThrottling: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0024": { + { + name: "PostgreSQL server checkpoint logging disabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Config: database.PostgresSQLConfig{ + Metadata: trivyTypes.NewTestMetadata(), + LogCheckpoints: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "PostgreSQL server checkpoint logging enabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Config: database.PostgresSQLConfig{ + Metadata: trivyTypes.NewTestMetadata(), + LogCheckpoints: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0019": { + { + name: "PostgreSQL server connection logging disabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Config: database.PostgresSQLConfig{ + Metadata: trivyTypes.NewTestMetadata(), + LogConnections: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "PostgreSQL server connection logging enabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Config: database.PostgresSQLConfig{ + Metadata: trivyTypes.NewTestMetadata(), + LogConnections: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0025": { + { + name: "MS SQL server auditing policy with retention period of 30 days", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + ExtendedAuditingPolicies: []database.ExtendedAuditingPolicy{ + { + Metadata: trivyTypes.NewTestMetadata(), + RetentionInDays: trivyTypes.Int(30, trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MS SQL server auditing policy with retention period of 90 days", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + ExtendedAuditingPolicies: []database.ExtendedAuditingPolicy{ + { + Metadata: trivyTypes.NewTestMetadata(), + RetentionInDays: trivyTypes.Int(90, trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0026": { + { + name: "MS SQL server minimum TLS version 1.0", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + MinimumTLSVersion: trivyTypes.String("1.0", trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MySQL server minimum TLS version 1.0", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MySQLServers: []database.MySQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + MinimumTLSVersion: trivyTypes.String("TLS1_0", trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "PostgreSQL server minimum TLS version 1.0", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + MinimumTLSVersion: trivyTypes.String("TLS1_0", trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MS SQL server minimum TLS version 1.2", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + MinimumTLSVersion: trivyTypes.String("1.2", trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + { + name: "MySQL server minimum TLS version 1.2", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MySQLServers: []database.MySQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + MinimumTLSVersion: trivyTypes.String("TLS1_2", trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + { + name: "PostgreSQL server minimum TLS version 1.2", + input: state.State{Azure: azure.Azure{Database: database.Database{ + PostgreSQLServers: []database.PostgreSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + Server: database.Server{ + Metadata: trivyTypes.NewTestMetadata(), + MinimumTLSVersion: trivyTypes.String("TLS1_2", trivyTypes.NewTestMetadata()), + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0018": { + { + name: "No email address provided for threat alerts", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + SecurityAlertPolicies: []database.SecurityAlertPolicy{ + { + Metadata: trivyTypes.NewTestMetadata(), + EmailAddresses: []trivyTypes.StringValue{}, + }, + }, + }, + }, + }}}, + expected: true, + }, + { + name: "Email address provided for threat alerts", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + SecurityAlertPolicies: []database.SecurityAlertPolicy{ + { + Metadata: trivyTypes.NewTestMetadata(), + EmailAddresses: []trivyTypes.StringValue{ + trivyTypes.String("sample@email.com", trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }, + }}}, + expected: false, + }, + }, + "AVD-AZU-0023": { + { + name: "MS SQL Server alert account admins disabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + SecurityAlertPolicies: []database.SecurityAlertPolicy{ + { + Metadata: trivyTypes.NewTestMetadata(), + EmailAccountAdmins: trivyTypes.Bool(false, trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }}}, + expected: true, + }, + { + name: "MS SQL Server alert account admins enabled", + input: state.State{Azure: azure.Azure{Database: database.Database{ + MSSQLServers: []database.MSSQLServer{ + { + Metadata: trivyTypes.NewTestMetadata(), + SecurityAlertPolicies: []database.SecurityAlertPolicy{ + { + Metadata: trivyTypes.NewTestMetadata(), + EmailAccountAdmins: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), + }, + }, + }, + }, + }}}, + expected: false, + }, + }, +} diff --git a/test/rego/rego_checks_test.go b/test/rego/rego_checks_test.go index 182d84f9..dd732448 100644 --- a/test/rego/rego_checks_test.go +++ b/test/rego/rego_checks_test.go @@ -60,14 +60,16 @@ func TestRegoChecks(t *testing.T) { azureAppServiceTestCases, azureAuthorizationTestCases, azureContainerTestCases, + azureDatabaseTestCases, + azureComputeTestCases, - googleDnsTestCases, + googleDnsTestCases, googleKmsTestCases, googleBigQueryTestCases, - githubTestCases, + githubTestCases, - nifcloudDnsTestCases, + nifcloudDnsTestCases, nifcloudNetworkTestCases, nifcloudSslCertificateTestCases, )