Skip to content

Commit 961242f

Browse files
authored
Network - 26884 - Bot protection rule set is enabled and assigned in Azure Front Door WAF (#1076)
* Fix 26884 - update logic & title * made changes as per copilot's suggestions * made changes as per Alek's suggestions
1 parent fb01c64 commit 961242f

1 file changed

Lines changed: 62 additions & 9 deletions

File tree

src/powershell/tests/Test-Assessment.26884.ps1

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function Test-Assessment-26884 {
2424
SfiPillar = 'Protect networks',
2525
TenantType = ('Workforce'),
2626
TestId = 26884,
27-
Title = 'Bot protection ruleset is enabled and assigned in Azure Front Door WAF',
27+
Title = 'Bot protection rule set is enabled and assigned in Azure Front Door WAF',
2828
UserImpact = 'Low'
2929
)]
3030
[CmdletBinding()]
@@ -131,6 +131,7 @@ resources
131131
PolicyName=name,
132132
SkuName=tostring(sku.name),
133133
EnabledState=tostring(properties.policySettings.enabledState),
134+
Mode=tostring(properties.policySettings.mode),
134135
ManagedRuleSets=properties.managedRules.managedRuleSets,
135136
SecurityPolicyLinks=properties.securityPolicyLinks,
136137
SubscriptionId=subscriptionId
@@ -183,13 +184,23 @@ resources
183184
$domainsProtected = 0
184185
$securityPolicyConfigured = 'No'
185186
$wafEnabled = 'N/A'
187+
$wafMode = 'N/A'
188+
$wafIsPremium = $false
189+
$hasEnabledRule = $false
186190

187191
if ($securityPolicies.Count -gt 0) {
188192
$securityPolicyConfigured = 'Yes'
189193

190194
foreach ($secPolicy in $securityPolicies) {
191195
# Reset domain count for each security policy to avoid accumulation
192196
$currentPolicyDomainCount = 0
197+
198+
# Reset Bot Manager-related fields for each security policy to avoid stale values
199+
$botManagerEnabled = 'No'
200+
$ruleSetVersion = 'N/A'
201+
$ruleSetAction = 'N/A'
202+
$hasEnabledRule = $false
203+
193204
$wafPolicyRef = $secPolicy.properties.parameters.wafPolicy.id
194205

195206
if ($wafPolicyRef) {
@@ -210,6 +221,7 @@ resources
210221
$wafPolicy = $wafPolicyLookup[$associatedWafPolicyId]
211222
$associatedWafPolicyName = $wafPolicy.PolicyName
212223
$wafEnabled = $wafPolicy.EnabledState
224+
$wafMode = $wafPolicy.Mode
213225
$wafIsPremium = $wafPolicy.SkuName -eq 'Premium_AzureFrontDoor'
214226

215227
# Check for Bot Manager rule set
@@ -226,8 +238,37 @@ resources
226238
$ruleSetAction = 'Per-rule defaults'
227239
}
228240

229-
# Check if WAF policy is enabled and Bot Manager is present
230-
if ($wafIsPremium -and $wafEnabled -eq 'Enabled') {
241+
# Check if at least one rule is enabled in the Bot Manager rule set
242+
# Rules are enabled by default unless explicitly disabled. Azure WAF managed rule
243+
# overrides typically list only changed rules; non-overridden rules remain enabled
244+
# by default. To avoid false negatives, we assume there is at least one enabled
245+
# rule unless we have conclusive evidence that the entire ruleset is disabled.
246+
$hasEnabledRule = $true
247+
if ($ruleSet.ruleGroupOverrides) {
248+
# We intentionally do not flip $hasEnabledRule to $false when all *overridden*
249+
# rules are disabled, because there may still be non-overridden (and thus
250+
# enabled) rules in the Bot Manager ruleset. Missing or empty overrides are
251+
# treated as default-enabled.
252+
foreach ($override in $ruleSet.ruleGroupOverrides) {
253+
if ($override.rules) {
254+
foreach ($rule in $override.rules) {
255+
if ($rule.enabledState -ne 'Disabled') {
256+
# At least one explicitly enabled/non-disabled rule found.
257+
# Keep $hasEnabledRule = $true and break out early.
258+
break
259+
}
260+
}
261+
}
262+
else {
263+
# No explicit rule overrides for this group: cannot conclude all rules
264+
# are disabled; non-overridden rules remain enabled by default.
265+
break
266+
}
267+
}
268+
}
269+
270+
# Check if WAF policy is enabled, in Prevention mode, and Bot Manager is present with at least one rule enabled
271+
if ($wafIsPremium -and $wafEnabled -eq 'Enabled' -and $wafMode -eq 'Prevention' -and $hasEnabledRule) {
231272
$hasValidBotProtection = $true
232273
# Only count domains from security policy with valid bot protection
233274
$domainsProtected = $currentPolicyDomainCount
@@ -255,9 +296,12 @@ resources
255296
ProfileId = $profileId
256297
SkuName = $fdProfile.SkuName
257298
WAFPolicyName = $associatedWafPolicyName
299+
WAFPolicyId = $associatedWafPolicyId
258300
WAFEnabled = $wafEnabled
301+
WAFMode = $wafMode
259302
SecurityPolicyConfigured = $securityPolicyConfigured
260303
BotManagerEnabled = $botManagerEnabled
304+
HasEnabledRule = $hasEnabledRule
261305
RuleSetVersion = $ruleSetVersion
262306
RuleSetAction = $ruleSetAction
263307
DomainsProtected = $domainsProtected
@@ -295,10 +339,10 @@ resources
295339
$passed = ($failedItems.Count -eq 0) -and ($passedItems.Count -gt 0)
296340

297341
if ($passed) {
298-
$testResultMarkdown = "Bot protection ruleset is enabled and assigned to Azure Front Door WAF, providing protection against malicious bot traffic.`n`n%TestResult%"
342+
$testResultMarkdown = "All Azure Front Door WAF policies attached to Azure Front Door are enabled, running in Prevention mode, and have the Bot Manager rule set (Microsoft_BotManagerRuleSet) with at least one rule enabled, providing protection against malicious bot traffic.`n`n%TestResult%"
299343
}
300344
else {
301-
$testResultMarkdown = "Bot protection ruleset is not enabled or not assigned to Azure Front Door WAF, leaving web applications vulnerable to automated attacks and malicious bots.`n`n%TestResult%"
345+
$testResultMarkdown = "One or more Azure Front Door WAF policies attached to Azure Front Door are disabled, running in Detection mode, do not have the Bot Manager rule set configured, or have all Bot Manager rules disabled, leaving web applications vulnerable to automated attacks and malicious bots.`n`n%TestResult%"
302346
}
303347

304348
#endregion Assessment Logic
@@ -316,8 +360,8 @@ resources
316360
if ($evaluationResults.Count -gt 0) {
317361
$tableRows = ""
318362
$formatTemplate = @'
319-
| Subscription | Profile name | SKU | WAF policy | Bot protection enabled | Rule set version | Rule set action | Domains protected | Status |
320-
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
363+
| Subscription | Profile name | SKU | WAF policy | WAF mode | Bot protection enabled | Enabled state | Rule set version | Rule set action | Domains protected | Status |
364+
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
321365
{0}
322366
323367
'@
@@ -326,8 +370,17 @@ resources
326370
$subscriptionLink = "[$(Get-SafeMarkdown $result.SubscriptionName)]($portalSubscriptionBaseLink/$($result.SubscriptionId)/overview)"
327371
$profileLink = "[$(Get-SafeMarkdown $result.ProfileName)]($portalResourceBaseLink$($result.ProfileId)/securityPolicies)"
328372
$statusText = if ($result.Status -eq 'Pass') { '✅ Pass' } else { '❌ Fail' }
373+
$wafModeDisplay = if ($result.WAFMode -eq 'Prevention') { '✅ Prevention' } else { "⚠️ $($result.WAFMode)" }
374+
$enabledStateDisplay = if ($result.WAFEnabled -eq 'Enabled') { '✅ Enabled' } else { '❌ Disabled' }
375+
376+
# Create WAF policy link if policy exists
377+
$wafPolicyDisplay = if ($result.WAFPolicyId) {
378+
"[$(Get-SafeMarkdown $result.WAFPolicyName)]($portalResourceBaseLink$($result.WAFPolicyId)/overview)"
379+
} else {
380+
$(Get-SafeMarkdown $result.WAFPolicyName)
381+
}
329382

330-
$tableRows += "| $subscriptionLink | $profileLink | $($result.SkuName) | $(Get-SafeMarkdown $result.WAFPolicyName) | $($result.BotManagerEnabled) | $($result.RuleSetVersion) | $($result.RuleSetAction) | $($result.DomainsProtected) | $statusText |`n"
383+
$tableRows += "| $subscriptionLink | $profileLink | $($result.SkuName) | $wafPolicyDisplay | $wafModeDisplay | $($result.BotManagerEnabled) | $enabledStateDisplay | $($result.RuleSetVersion) | $($result.RuleSetAction) | $($result.DomainsProtected) | $statusText |`n"
331384
}
332385

333386
$mdInfo += $formatTemplate -f $tableRows
@@ -369,7 +422,7 @@ resources
369422

370423
$params = @{
371424
TestId = '26884'
372-
Title = 'Bot protection ruleset is enabled and assigned in Azure Front Door WAF'
425+
Title = 'Bot protection rule set is enabled and assigned in Azure Front Door WAF'
373426
Status = $passed
374427
Result = $testResultMarkdown
375428
}

0 commit comments

Comments
 (0)