diff --git a/.vscode/markdown.code-snippets b/.vscode/markdown.code-snippets index 7fc4c3250b..d0a29627ca 100644 --- a/.vscode/markdown.code-snippets +++ b/.vscode/markdown.code-snippets @@ -65,7 +65,7 @@ }, "rule-azure-example-arm": { "scope": "markdown", - "prefix": "rule-azure-example-arm", + "prefix": "example-arm", "description": "Example for Azure template", "body": [ "### Configure with Azure template", @@ -83,7 +83,7 @@ }, "rule-azure-example-cli": { "scope": "markdown", - "prefix": "rule-azure-example-cli", + "prefix": "example-cli", "description": "Example for Azure CLI", "body": [ "### Configure with Azure CLI", @@ -95,7 +95,7 @@ }, "rule-azure-example-pwsh": { "scope": "markdown", - "prefix": "rule-azure-example-pwsh", + "prefix": "example-pwsh", "description": "Example for Azure PowerShell", "body": [ "### Configure with Azure PowerShell", @@ -107,7 +107,7 @@ }, "rule-azure-example-bicep": { "scope": "markdown", - "prefix": "rule-azure-example-bicep", + "prefix": "example-bicep", "description": "Example for Bicep", "body": [ "### Configure with Bicep", @@ -123,27 +123,15 @@ "```" ] }, - "rule-azure-example-bicep-br": { + "rule-azure-example-bicep-avm": { "scope": "markdown", - "prefix": "rule-azure-example-bicep-br", - "description": "Example for Bicep Public Registry", - "body": [ - "### Configure with Bicep Public Registry", - "", - "To deploy ${1:resource} that pass this rule:", - "", - "- ${2:steps}", - "", - "For example:", - "", - "```bicep", - "", - "```" - ] + "prefix": "example-avm", + "description": "Link to AVM example for Bicep", + "body": "" }, "rule-azure-example-policy": { "scope": "markdown", - "prefix": "rule-azure-example-policy", + "prefix": "example-policy", "description": "Example for Azure Policy", "body": [ "### Configure with Azure Policy", diff --git a/data/policy-ignore.json b/data/policy-ignore.json index c95955383a..37f13ec93c 100644 --- a/data/policy-ignore.json +++ b/data/policy-ignore.json @@ -244,5 +244,20 @@ ], "reason": "Duplicate", "value": "Azure.AppService.PHPVersion" + }, + { + "policyDefinitionIds": [ + "/providers/Microsoft.Authorization/policyDefinitions/32e6bbec-16b6-44c2-be37-c5b672d103cf" + ], + "reason": "Duplicate", + "value": "Azure.SQL.MinTLS" + }, + { + "policyDefinitionIds": [ + "/providers/Microsoft.Authorization/policyDefinitions/a6fb4358-5bf4-4ad7-ba82-2cd2f41ce5e9", + "/providers/Microsoft.Authorization/policyDefinitions/f4c68484-132f-41f9-9b6d-3e4b1cb55036" + ], + "reason": "Duplicate", + "value": "Azure.SQL.Auditing" } ] diff --git a/docs/CHANGELOG-v1.md b/docs/CHANGELOG-v1.md index ef908e1f63..a6339ff5bb 100644 --- a/docs/CHANGELOG-v1.md +++ b/docs/CHANGELOG-v1.md @@ -44,8 +44,11 @@ What's changed since v1.35.3: - Check that database accounts only accept a minimum of TLS 1.2 by @BernieWhite. [#2809](https://github.com/Azure/PSRule.Rules.Azure/issues/2809) - General improvements: - - Quality updates to documentation by @lukemurraynz. + - Quality updates to documentation by @lukemurraynz @BernieWhite. [#2789](https://github.com/Azure/PSRule.Rules.Azure/pull/2789) + [#2570](https://github.com/Azure/PSRule.Rules.Azure/issues/2570) + - Additional policies added to default ignore list by @BernieWhite. + [#1731](https://github.com/Azure/PSRule.Rules.Azure/issues/1731) - Bug fixes: - Fixed not found warning when exporting firewall policy `signatureOverrides` by @BernieWhite. [#2806](https://github.com/Azure/PSRule.Rules.Azure/issues/2806) diff --git a/docs/en/rules/Azure.ContainerApp.AvailabilityZone.md b/docs/en/rules/Azure.ContainerApp.AvailabilityZone.md index 78ac082d76..ff60841f38 100644 --- a/docs/en/rules/Azure.ContainerApp.AvailabilityZone.md +++ b/docs/en/rules/Azure.ContainerApp.AvailabilityZone.md @@ -99,6 +99,8 @@ resource containerEnv 'Microsoft.App/managedEnvironments@2023-05-01' = { } ``` + + ## LINKS - [RE:05 Regions and availability zones](https://learn.microsoft.com/azure/well-architected/reliability/regions-availability-zones) diff --git a/docs/en/rules/Azure.ContainerApp.ExternalIngress.md b/docs/en/rules/Azure.ContainerApp.ExternalIngress.md index a7cc1bed07..e1ffcaa411 100644 --- a/docs/en/rules/Azure.ContainerApp.ExternalIngress.md +++ b/docs/en/rules/Azure.ContainerApp.ExternalIngress.md @@ -111,6 +111,8 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = { } ``` + + ## NOTES This rule is skipped by default because there are common cases where external ingress is required. diff --git a/docs/en/rules/Azure.ContainerApp.Insecure.md b/docs/en/rules/Azure.ContainerApp.Insecure.md index 369a63382d..1b1a7411c6 100644 --- a/docs/en/rules/Azure.ContainerApp.Insecure.md +++ b/docs/en/rules/Azure.ContainerApp.Insecure.md @@ -104,6 +104,8 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = { } ``` + + ### Configure with Azure Policy To address this issue at runtime use the following policies: diff --git a/docs/en/rules/Azure.ContainerApp.ManagedIdentity.md b/docs/en/rules/Azure.ContainerApp.ManagedIdentity.md index 1309ceda80..3885a69245 100644 --- a/docs/en/rules/Azure.ContainerApp.ManagedIdentity.md +++ b/docs/en/rules/Azure.ContainerApp.ManagedIdentity.md @@ -111,6 +111,8 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = { } ``` + + ### Configure with Azure Policy To address this issue at runtime use the following policies: diff --git a/docs/en/rules/Azure.EventHub.DisableLocalAuth.md b/docs/en/rules/Azure.EventHub.DisableLocalAuth.md index 8b8a145cc3..69a99be407 100644 --- a/docs/en/rules/Azure.EventHub.DisableLocalAuth.md +++ b/docs/en/rules/Azure.EventHub.DisableLocalAuth.md @@ -89,6 +89,8 @@ resource ns 'Microsoft.EventHub/namespaces@2024-01-01' = { } ``` + + ### Configure with Azure Policy To address this issue at runtime use the following policies: diff --git a/docs/en/rules/Azure.EventHub.MinTLS.md b/docs/en/rules/Azure.EventHub.MinTLS.md index 8b28f48627..382b3fb283 100644 --- a/docs/en/rules/Azure.EventHub.MinTLS.md +++ b/docs/en/rules/Azure.EventHub.MinTLS.md @@ -21,9 +21,12 @@ Older TLS versions are no longer considered secure by industry standards, such a Azure lets you disable outdated protocols and require connections to use a minimum of TLS 1.2. By default, TLS 1.0, TLS 1.1, and TLS 1.2 is accepted. +When clients connect using an older version of TLS that is disabled, the connection will fail. + ## RECOMMENDATION Configure the minimum supported TLS version to be 1.2. +Also consider enforcing this setting using Azure Policy. ## EXAMPLES @@ -87,9 +90,12 @@ resource ns 'Microsoft.EventHub/namespaces@2024-01-01' = { } ``` + + ## LINKS -- [SE:07 Encryption](https://learn.microsoft.com/azure/well-architected/security/encryption) +- [SE:07 Encryption](https://learn.microsoft.com/azure/well-architected/security/encryption#data-in-transit) +- [DP-3: Encrypt sensitive data in transit](https://learn.microsoft.com/security/benchmark/azure/baselines/event-hubs-security-baseline#dp-3-encrypt-sensitive-data-in-transit) - [Enforce a minimum required version of Transport Layer Security (TLS) for requests to an Event Hubs namespace](https://learn.microsoft.com/azure/event-hubs/transport-layer-security-enforce-minimum-version) - [Preparing for TLS 1.2 in Microsoft Azure](https://azure.microsoft.com/updates/azuretls12/) - [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.eventhub/namespaces) diff --git a/docs/en/rules/Azure.SQL.Auditing.md b/docs/en/rules/Azure.SQL.Auditing.md index e29e823550..968b929d16 100644 --- a/docs/en/rules/Azure.SQL.Auditing.md +++ b/docs/en/rules/Azure.SQL.Auditing.md @@ -1,7 +1,8 @@ --- +reviewed: 2024-04-15 severity: Important pillar: Security -category: Security operations +category: SE:10 Monitoring and threat detection resource: SQL Database online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.SQL.Auditing/ ms-content-id: d6084913-9ff9-40b6-a65b-30fcd4d49251 @@ -16,11 +17,22 @@ Enable auditing for Azure SQL logical server. ## DESCRIPTION Auditing for Azure SQL Database tracks database events and writes them to an audit log. -Audit logs help you find suspicious events, unusual activity, and trends. +Data collected from auditing can be used to help find suspicious events, unusual activity, and trends. + +When managing security events at scale, it is important to have a centralized location to store and analyze security data. +A security information and event management (SIEM) system to consolidate security data in a central location. +Once the security data is in a central location it can be correlated across various services. +Security orchestration, automation, and response (SOAR) tools can be used to automate responses to security events. + +Microsoft Sentinel is a scalable, cloud-native solution that provides: + +- Security information and event management (SIEM). +- Security orchestration, automation, and response (SOAR). ## RECOMMENDATION Consider enabling auditing for each SQL Database logical server and review reports on a regular basis. +Also consider enforcing this setting using Azure Policy. ## EXAMPLES @@ -113,7 +125,19 @@ az sql server audit-policy update -g '' -n '' --sta Set-AzSqlServerAudit -ResourceGroupName '' -ServerName '' -BlobStorageTargetState Enabled -StorageAccountResourceId '' ``` +### Configure with Azure Policy + +To address this issue at runtime use the following policies: + +- [Auditing on SQL server should be enabled](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/SQL/SqlServerAuditing_Audit.json) + `/providers/Microsoft.Authorization/policyDefinitions/a6fb4358-5bf4-4ad7-ba82-2cd2f41ce5e9` +- [Configure SQL servers to have auditing enabled](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/SQL/SqlServerAuditing_DINE.json) + `/providers/Microsoft.Authorization/policyDefinitions/f4c68484-132f-41f9-9b6d-3e4b1cb55036` + ## LINKS +- [SE:10 Monitoring and threat detection](https://learn.microsoft.com/azure/well-architected/security/monitor-threats) +- [LT-3: Enable logging for security investigation](https://learn.microsoft.com/security/benchmark/azure/baselines/azure-sql-security-baseline#logging-and-threat-detection) - [Auditing for Azure SQL Database and Azure Synapse Analytics](https://learn.microsoft.com/azure/azure-sql/database/auditing-overview) +- [What is Microsoft Sentinel?](https://learn.microsoft.com/azure/sentinel/overview) - [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.sql/servers/auditingsettings) diff --git a/docs/en/rules/Azure.SQL.MinTLS.md b/docs/en/rules/Azure.SQL.MinTLS.md index 33be5e087c..a0dadbbe0f 100644 --- a/docs/en/rules/Azure.SQL.MinTLS.md +++ b/docs/en/rules/Azure.SQL.MinTLS.md @@ -1,7 +1,8 @@ --- +reviewed: 2024-04-15 severity: Critical pillar: Security -category: Encryption +category: SE:07 Encryption resource: SQL Database online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.SQL.MinTLS/ --- @@ -20,9 +21,12 @@ Older TLS versions are no longer considered secure by industry standards, such a Azure lets you disable outdated protocols and require connections to use a minimum of TLS 1.2. By default, TLS 1.0, TLS 1.1, and TLS 1.2 is accepted. +When clients connect using an older version of TLS that is disabled, the connection will fail. + ## RECOMMENDATION Consider configuring the minimum supported TLS version to be 1.2. +Also consider enforcing this setting using Azure Policy. ## EXAMPLES @@ -85,9 +89,19 @@ resource server 'Microsoft.Sql/servers@2022-11-01-preview' = { } ``` + + +### Configure with Azure Policy + +To address this issue at runtime use the following policies: + +- [Azure SQL Database should be running TLS version 1.2 or newer](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/SQL/SqlServer_MiniumTLSVersion_Audit.json) + `/providers/Microsoft.Authorization/policyDefinitions/32e6bbec-16b6-44c2-be37-c5b672d103cf` + ## LINKS -- [Data encryption in Azure](https://learn.microsoft.com/azure/architecture/framework/security/design-storage-encryption#data-in-transit) +- [SE:07 Encryption](https://learn.microsoft.com/azure/well-architected/security/encryption#data-in-transit) +- [DP-3: Encrypt sensitive data in transit](https://learn.microsoft.com/security/benchmark/azure/baselines/azure-sql-security-baseline#dp-3-encrypt-sensitive-data-in-transit) - [Minimal TLS Version](https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings#minimal-tls-version) - [Preparing for TLS 1.2 in Microsoft Azure](https://azure.microsoft.com/updates/azuretls12/) - [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.sql/servers#serverproperties) diff --git a/docs/en/rules/Azure.ServiceBus.DisableLocalAuth.md b/docs/en/rules/Azure.ServiceBus.DisableLocalAuth.md index fc7d80107f..738e0a1252 100644 --- a/docs/en/rules/Azure.ServiceBus.DisableLocalAuth.md +++ b/docs/en/rules/Azure.ServiceBus.DisableLocalAuth.md @@ -81,6 +81,8 @@ resource ns 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' = { } ``` + + ### Configure with Azure Policy To address this issue at runtime use the following policies: diff --git a/docs/en/rules/Azure.ServiceBus.MinTLS.md b/docs/en/rules/Azure.ServiceBus.MinTLS.md index aa0d0dc783..6dd5ccedc5 100644 --- a/docs/en/rules/Azure.ServiceBus.MinTLS.md +++ b/docs/en/rules/Azure.ServiceBus.MinTLS.md @@ -28,7 +28,7 @@ When clients connect using an older version of TLS that is disabled, the connect ## RECOMMENDATION Consider configuring the minimum supported TLS version for Service Bus clients to be 1.2. -Support for TLS 1.0/ 1.1 version will be removed. +Also consider enforcing this setting using Azure Policy. ## EXAMPLES @@ -84,6 +84,8 @@ resource ns 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' = { } ``` + + ### Configure with Azure CLI ```bash diff --git a/docs/en/rules/Azure.Storage.MinTLS.md b/docs/en/rules/Azure.Storage.MinTLS.md index 4bc99a4311..86be6fcaed 100644 --- a/docs/en/rules/Azure.Storage.MinTLS.md +++ b/docs/en/rules/Azure.Storage.MinTLS.md @@ -21,6 +21,8 @@ Older TLS versions are no longer considered secure by industry standards, such a Storage Accounts lets you disable outdated protocols and enforce TLS 1.2. By default, TLS 1.0, TLS 1.1, and TLS 1.2 is accepted. +When clients connect using an older version of TLS that is disabled, the connection will fail. + ## RECOMMENDATION Consider configuring the minimum supported TLS version to be 1.2. diff --git a/docs/examples-sql.bicep b/docs/examples-sql.bicep index 1c56efe191..1f00dd62bd 100644 --- a/docs/examples-sql.bicep +++ b/docs/examples-sql.bicep @@ -13,7 +13,7 @@ param adminLogin string param adminPrincipalId string // An example Azure SQL Database logical server. -resource server 'Microsoft.Sql/servers@2022-11-01-preview' = { +resource server 'Microsoft.Sql/servers@2023-08-01-preview' = { name: name location: location identity: { @@ -34,7 +34,7 @@ resource server 'Microsoft.Sql/servers@2022-11-01-preview' = { } // An example administrator configuration for an Azure SQL Database logical server. -resource sqlAdministrator 'Microsoft.Sql/servers/administrators@2022-02-01-preview' = { +resource sqlAdministrator 'Microsoft.Sql/servers/administrators@2023-08-01-preview' = { parent: server name: 'ActiveDirectory' properties: { @@ -45,7 +45,7 @@ resource sqlAdministrator 'Microsoft.Sql/servers/administrators@2022-02-01-previ } // An example configuration to enable SQL Advanced Threat Protection for an Azure SQL Database logical server. -resource defenderSql 'Microsoft.Sql/servers/securityAlertPolicies@2022-11-01-preview' = { +resource defenderSql 'Microsoft.Sql/servers/securityAlertPolicies@2023-08-01-preview' = { name: 'default' parent: server properties: { @@ -54,7 +54,7 @@ resource defenderSql 'Microsoft.Sql/servers/securityAlertPolicies@2022-11-01-pre } // An example configuration to enable Azure SQL auditing for an Azure SQL Database logical server. -resource sqlAuditSettings 'Microsoft.Sql/servers/auditingSettings@2022-08-01-preview' = { +resource sqlAuditSettings 'Microsoft.Sql/servers/auditingSettings@2023-08-01-preview' = { name: 'default' parent: server properties: { diff --git a/docs/examples-sql.json b/docs/examples-sql.json index cc24449c29..07b9d16d8d 100644 --- a/docs/examples-sql.json +++ b/docs/examples-sql.json @@ -1,13 +1,11 @@ { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", "contentVersion": "1.0.0.0", "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", "_generator": { "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "2836760249200186240" + "version": "0.26.170.59819", + "templateHash": "6875576904803423253" } }, "parameters": { @@ -31,12 +29,15 @@ "type": "string" } }, - "resources": { - "server": { + "resources": [ + { "type": "Microsoft.Sql/servers", - "apiVersion": "2022-11-01-preview", + "apiVersion": "2023-08-01-preview", "name": "[parameters('name')]", "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, "properties": { "publicNetworkAccess": "Disabled", "minimalTlsVersion": "1.2", @@ -50,9 +51,9 @@ } } }, - "sqlAdministrator": { + { "type": "Microsoft.Sql/servers/administrators", - "apiVersion": "2022-02-01-preview", + "apiVersion": "2023-08-01-preview", "name": "[format('{0}/{1}', parameters('name'), 'ActiveDirectory')]", "properties": { "administratorType": "ActiveDirectory", @@ -60,23 +61,23 @@ "sid": "[parameters('adminPrincipalId')]" }, "dependsOn": [ - "server" + "[resourceId('Microsoft.Sql/servers', parameters('name'))]" ] }, - "defenderSql": { + { "type": "Microsoft.Sql/servers/securityAlertPolicies", - "apiVersion": "2022-11-01-preview", + "apiVersion": "2023-08-01-preview", "name": "[format('{0}/{1}', parameters('name'), 'default')]", "properties": { "state": "Enabled" }, "dependsOn": [ - "server" + "[resourceId('Microsoft.Sql/servers', parameters('name'))]" ] }, - "sqlAuditSettings": { + { "type": "Microsoft.Sql/servers/auditingSettings", - "apiVersion": "2022-08-01-preview", + "apiVersion": "2023-08-01-preview", "name": "[format('{0}/{1}', parameters('name'), 'default')]", "properties": { "isAzureMonitorTargetEnabled": true, @@ -89,8 +90,8 @@ ] }, "dependsOn": [ - "server" + "[resourceId('Microsoft.Sql/servers', parameters('name'))]" ] } - } + ] } \ No newline at end of file diff --git a/src/PSRule.Rules.Azure/rules/Azure.SQL.Rule.ps1 b/src/PSRule.Rules.Azure/rules/Azure.SQL.Rule.ps1 index c35b3fb736..5f78c11b0a 100644 --- a/src/PSRule.Rules.Azure/rules/Azure.SQL.Rule.ps1 +++ b/src/PSRule.Rules.Azure/rules/Azure.SQL.Rule.ps1 @@ -43,8 +43,8 @@ Rule 'Azure.SQL.DefenderCloud' -Alias 'Azure.SQL.ThreatDetection' -Ref 'AZR-0001 } } -# Synopsis: Enable auditing for Azure SQL logical server -Rule 'Azure.SQL.Auditing' -Ref 'AZR-000187' -Type 'Microsoft.Sql/servers' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } { +# Synopsis: Enable auditing for Azure SQL logical server. +Rule 'Azure.SQL.Auditing' -Ref 'AZR-000187' -Type 'Microsoft.Sql/servers' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } -Labels @{ 'Azure.MCSB.v1/control' = 'LT-3' } { $configs = @(GetSubResources -ResourceType 'Microsoft.Sql/servers/auditingSettings'); if ($configs.Length -eq 0) { return $Assert.Fail($LocalizedData.SubResourceNotFound, 'Microsoft.Sql/servers/auditingSettings'); diff --git a/src/PSRule.Rules.Azure/rules/Azure.SQL.Rule.yaml b/src/PSRule.Rules.Azure/rules/Azure.SQL.Rule.yaml index 7e428e79bc..40e02b3e9b 100644 --- a/src/PSRule.Rules.Azure/rules/Azure.SQL.Rule.yaml +++ b/src/PSRule.Rules.Azure/rules/Azure.SQL.Rule.yaml @@ -15,11 +15,11 @@ metadata: name: Azure.SQL.MinTLS ref: AZR-000189 tags: - release: 'GA' - ruleSet: '2020_09' - Azure.WAF/pillar: 'Security' + release: GA + ruleSet: 2020_09 + Azure.WAF/pillar: Security labels: - Azure.MCSB.v1/control: 'DP-3' + Azure.MCSB.v1/control: DP-3 spec: type: - Microsoft.Sql/servers diff --git a/tests/PSRule.Rules.Azure.Tests/PolicyAssignmentVisitorTests.cs b/tests/PSRule.Rules.Azure.Tests/PolicyAssignmentVisitorTests.cs index 65bdfa3afb..1dfe50f6df 100644 --- a/tests/PSRule.Rules.Azure.Tests/PolicyAssignmentVisitorTests.cs +++ b/tests/PSRule.Rules.Azure.Tests/PolicyAssignmentVisitorTests.cs @@ -95,7 +95,7 @@ public void GetPolicyDefinitionWithIgnore() var definitions = context.GetDefinitions(); Assert.NotNull(definitions); - Assert.Equal(114, definitions.Length); + Assert.Equal(113, definitions.Length); // Check category and version var actual = definitions.FirstOrDefault(definition => definition.DefinitionId == "/providers/Microsoft.Authorization/policyDefinitions/34c877ad-507e-4c82-993e-3452a6e0ad3c");