tests/Test-Assessment.25543.ps1
|
<#
.SYNOPSIS Validates that Azure Front Door WAF is enabled in Prevention Mode. .DESCRIPTION This test validates that Azure Front Door Web Application Firewall policies are configured in Prevention mode to actively block malicious requests. Checks all Front Door WAF policies across all subscriptions and reports their prevention/detection mode status. .NOTES Test ID: 25543 Category: Azure Network Security Required API: Azure Front Door WAF Policies #> function Test-Assessment-25543 { [ZtTest( Category = 'Azure Network Security', ImplementationCost = 'Low', MinimumLicense = ('Azure WAF on Azure Front Door Premium SKU', 'Azure Standard SKU'), Pillar = 'Network', RiskLevel = 'High', SfiPillar = 'Protect networks', TenantType = ('Workforce'), TestId = 25543, Title = 'Azure Front Door WAF is Enabled in Prevention Mode', UserImpact = 'Low' )] [CmdletBinding()] param() #region Data Collection Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose $activity = 'Checking Azure Front Door WAF policies configuration' # Check if connected to Azure Write-ZtProgress -Activity $activity -Status 'Checking Azure connection' $azContext = Get-AzContext -ErrorAction SilentlyContinue if (-not $azContext) { Write-PSFMessage 'Not connected to Azure.' -Level Warning Add-ZtTestResultDetail -SkippedBecause NotConnectedAzure return } Write-ZtProgress -Activity $activity -Status 'Enumerating subscriptions' # Initialize variables $subscriptions = @() $policies = @() $anySuccessfulAccess = 0 $apiVersion = "2025-03-01" try { $subscriptions = Get-AzSubscription -ErrorAction Stop } catch { Write-PSFMessage "Unable to retrieve Azure subscriptions: $_" -Level Warning } if ($subscriptions.Count -eq 0) { Write-PSFMessage "No Azure subscriptions found." -Level Warning Add-ZtTestResultDetail -SkippedBecause NoAzureAccess return } # Collect WAF policies from all subscriptions foreach ($sub in $subscriptions) { Write-ZtProgress -Activity $activity -Status "Checking subscription: $($sub.Name)" $path = "/subscriptions/$($sub.Id)/providers/Microsoft.Network/FrontDoorWebApplicationFirewallPolicies?api-version=$apiVersion" $response = Invoke-AzRestMethod -Path $path -ErrorAction SilentlyContinue # Skip if request failed completely if (-not $response -or $null -eq $response.StatusCode) { Write-PSFMessage "Failed to query subscription '$($sub.Name)'. Skipping." -Level Warning continue } # Handle access denied for this subscription - skip and continue to next if ($response.StatusCode -eq 403) { Write-PSFMessage "Access denied to subscription '$($sub.Name)': HTTP $($response.StatusCode). Skipping." -Level Verbose continue } # Handle other HTTP errors - skip this subscription if ($response.StatusCode -ge 400) { Write-PSFMessage "Error querying subscription '$($sub.Name)': HTTP $($response.StatusCode). Skipping." -Level Warning continue } # Count successful accesses $anySuccessfulAccess++ # No content or no policies in this subscription if (-not $response.Content) { continue } $policiesJson = $response.Content | ConvertFrom-Json if (-not $policiesJson.value -or $policiesJson.value.Count -eq 0) { continue } # Collect policies from this subscription foreach ($policyResource in $policiesJson.value) { $policies += [PSCustomObject]@{ SubscriptionId = $sub.Id SubscriptionName = $sub.Name PolicyName = $policyResource.name PolicyId = $policyResource.id EnabledState = $policyResource.properties.policySettings.enabledState Mode = $policyResource.properties.policySettings.mode } } } #endregion Data Collection #region Assessment Logic $passed = $false # Skip test if no policies found if ($policies.Count -eq 0) { if ($anySuccessfulAccess -eq 0) { # All subscriptions were inaccessible Write-PSFMessage "No accessible Azure subscriptions found." -Level Warning Add-ZtTestResultDetail -SkippedBecause NoAzureAccess } else { # Subscriptions accessible but no WAF policies deployed Write-PSFMessage "No Azure Front Door WAF policies found across subscriptions." -Tag Test -Level Verbose Add-ZtTestResultDetail -SkippedBecause NotApplicable } return } # Check if all policies are enabled and in Prevention mode $allCompliant = $true foreach ($policy in $policies) { if ($policy.EnabledState -ne 'Enabled' -or $policy.Mode -ne 'Prevention') { $allCompliant = $false break } } if ($allCompliant) { $passed = $true $testResultMarkdown = "✅ All Azure Front Door WAF policies are enabled in **Prevention** mode.`n`n%TestResult%" } else { $passed = $false $testResultMarkdown = "❌ One or more Azure Front Door WAF policies are either in **Disabled** state or in **Detection** mode.`n`n%TestResult%" } #endregion Assessment Logic #region Report Generation $mdInfo = '' # Table title $reportTitle = 'Azure Front Door WAF policies' $portalLink = "https://portal.azure.com/#view/Microsoft_Azure_HybridNetworking/FirewallManagerMenuBlade/~/wafMenuItem" # Prepare table rows $tableRows = '' foreach ($item in $policies) { $policyLink = "https://portal.azure.com/#resource$($item.PolicyId)" $subLink = "https://portal.azure.com/#resource/subscriptions/$($item.SubscriptionId)" $policyMd = "[$(Get-SafeMarkdown $item.PolicyName)]($policyLink)" $subMd = "[$(Get-SafeMarkdown $item.SubscriptionName)]($subLink)" # Calculate status indicators $policyStatus = if ($item.EnabledState -eq 'Enabled' -and $item.Mode -eq 'Prevention') { '✅' } else { '❌' } $modeDisplay = if ($item.Mode -eq 'Prevention') { '✅ Prevention' } else { '❌ Detection' } $enabledStateDisplay = if ($item.EnabledState -eq 'Enabled') { '✅ Enabled' } else { '❌ Disabled' } $tableRows += "| $policyMd | $subMd | $enabledStateDisplay | $modeDisplay | $policyStatus |`n" } $formatTemplate = @' ## [{0}]({1}) | Policy name | Subscription name | Policy state | Mode | Status | | :---------- | :---------------- | :----------: | :--: | :----: | {2} '@ $mdInfo = $formatTemplate -f $reportTitle, $portalLink, $tableRows.TrimEnd("`n") $testResultMarkdown = $testResultMarkdown -replace '%TestResult%', $mdInfo #endregion Report Generation $params = @{ TestId = '25543' Title = 'Azure Front Door WAF is Enabled in Prevention Mode' Status = $passed Result = $testResultMarkdown } Add-ZtTestResultDetail @params } |