Private/New-AzureUtilsInsecureConfigQuery.ps1
|
function New-AzureUtilsInsecureConfigQuery { <# .SYNOPSIS Builds the Resource Graph (KQL) query for insecure resource configuration. .DESCRIPTION Pure, side-effect-free. Returns a union of the selected hardening checks, each projecting the same columns plus a 'finding' explaining the weakness. Focuses on configuration weaknesses (weak TLS, no HTTPS enforcement, no purge protection) rather than public exposure, which is covered by Find-AzureUtilsPublicResource. .PARAMETER Type Which insecure-config checks to include. Defaults to all. .OUTPUTS System.String (the KQL query) #> [CmdletBinding()] [OutputType([string])] param( [ValidateSet('StorageInsecureTransfer', 'StorageWeakTls', 'WebAppHttpsOnly', 'KeyVaultNoPurgeProtection')] [string[]] $Type = @('StorageInsecureTransfer', 'StorageWeakTls', 'WebAppHttpsOnly', 'KeyVaultNoPurgeProtection') ) $cols = 'id, name, type, resourceGroup, location, subscriptionId, tags, finding' $subQueries = [System.Collections.Generic.List[string]]::new() if ($Type -contains 'StorageInsecureTransfer') { $subQueries.Add(@" resources | where type =~ 'microsoft.storage/storageaccounts' and properties.supportsHttpsTrafficOnly == false | extend finding = 'Storage allows non-HTTPS traffic (supportsHttpsTrafficOnly = false)' | project $cols "@) } if ($Type -contains 'StorageWeakTls') { $subQueries.Add(@" resources | where type =~ 'microsoft.storage/storageaccounts' and tostring(properties.minimumTlsVersion) in~ ('TLS1_0', 'TLS1_1') | extend finding = strcat('Storage minimum TLS version is ', tostring(properties.minimumTlsVersion)) | project $cols "@) } if ($Type -contains 'WebAppHttpsOnly') { $subQueries.Add(@" resources | where type =~ 'microsoft.web/sites' and properties.httpsOnly == false | extend finding = 'Web app does not enforce HTTPS-only' | project $cols "@) } if ($Type -contains 'KeyVaultNoPurgeProtection') { # enablePurgeProtection is absent (null) or false when protection is off. $subQueries.Add(@" resources | where type =~ 'microsoft.keyvault/vaults' and properties.enablePurgeProtection != true | extend finding = 'Key Vault purge protection is disabled' | project $cols "@) } if ($subQueries.Count -eq 1) { return $subQueries[0] } # Azure Resource Graph requires the query to start with a table, then chain # '| union (subquery)' for the remaining checks. $query = $subQueries[0] for ($i = 1; $i -lt $subQueries.Count; $i++) { $query += "`n| union (`n$($subQueries[$i])`n)" } return $query } |