-
Notifications
You must be signed in to change notification settings - Fork 124
Network-25537: Threat intelligence is Enabled in Deny Mode on Azure Firewall #736
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| Azure Firewall Threat intelligence-based filtering alerts and denies traffic from/to known malicious IP addresses, FQDNs, and URLs. The IP addresses, domains, and URLs are sourced from the Microsoft Threat Intelligence feed, which includes multiple sources including the Microsoft Cyber Security team. When threat intelligence-based filtering is enabled, Azure Firewall evaluates traffic against the threat intelligence rules before applying NAT, network, or application rules. | ||
|
|
||
| This check verifies that Threat Intelligence feature is enabled in “Alert and Deny” mode in the Azure Firewall policy configuration. The check will fail if Threat Intelligence is either “Disabled” or if it is not configured in “Alert and Deny” mode, in the firewall policy attached to the firewall. | ||
|
|
||
| **Remediation action** | ||
|
|
||
| Please check this article for guidance on how to enable Threat Intelligence in “Alert and Deny” mode in the Azure Firewall Policy: | ||
|
Comment on lines
+3
to
+7
|
||
| - [Azure Firewall threat intelligence configuration | Microsoft Learn](https://learn.microsoft.com/en-us/azure/firewall-manager/threat-intelligence-settings) | ||
|
|
||
| <!--- Results ---> | ||
| %TestResult% | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,140 @@ | ||||||||||||||||||||||||||
| <# | ||||||||||||||||||||||||||
| .SYNOPSIS | ||||||||||||||||||||||||||
| Validates Threat intelligence is Enabled in Deny Mode on Azure Firewall. | ||||||||||||||||||||||||||
| .DESCRIPTION | ||||||||||||||||||||||||||
| This test validates that Azure Firewall Policies have Threat Intelligence enabled in Deny mode. | ||||||||||||||||||||||||||
| Checks all firewall policies in the subscription and reports their threat intelligence status. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
| Checks all firewall policies in the subscription and reports their threat intelligence status. | |
| Checks all firewall policies across all accessible subscriptions and reports their threat intelligence status. |
Copilot
AI
Jan 19, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Set-AzContext is invoked without -ErrorAction Stop / error handling. If context switching fails, the loop may continue using a previous context and attribute results to the wrong subscription. Please make context switching a terminating operation and handle failures explicitly (e.g., try/catch per subscription and continue/skip as appropriate).
| Set-AzContext -SubscriptionId $sub.Id | Out-Null | |
| # Get all firewall policies in the subscription | |
| $policies = Get-AzResource -ResourceType 'Microsoft.Network/firewallPolicies' -ErrorAction Stop | |
| try { | |
| Set-AzContext -SubscriptionId $sub.Id -ErrorAction Stop | Out-Null | |
| # Get all firewall policies in the subscription | |
| $policies = Get-AzResource -ResourceType 'Microsoft.Network/firewallPolicies' -ErrorAction Stop | |
| } | |
| catch { | |
| Write-PSFMessage "Failed to set context or enumerate firewall policies for subscription '$($sub.Id)': $($_.Exception.Message)" -Tag Test -Level Error | |
| continue | |
| } |
Copilot
AI
Jan 19, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test uses Az cmdlets (Get-AzSubscription/Set-AzContext/Get-AzResource) but doesn’t follow the repo’s established Azure-connection handling. If the user isn’t connected to Azure or lacks subscription access, this will error rather than producing a skipped result. Consider following the pattern used in src/powershell/tests/Test-Assessment.21788.ps1:27-55 and Test-Assessment.21860.ps1:33-60 (Get-AzAccessToken check + catch 403) and call Add-ZtTestResultDetail -SkippedBecause NotConnectedAzure/NoAzureAccess accordingly.
Copilot
AI
Jan 19, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When no firewall policies are found, the function returns without calling Add-ZtTestResultDetail. Since results are collected via Add-ZtTestResultDetail, this test will produce no report entry in that case. Please emit an explicit result (pass/not-applicable or a skipped status via -SkippedBecause NotSupported) instead of returning silently.
| Write-PSFMessage 'No Azure Firewall policies found. Skipping test.' -Tag Firewall -Level Verbose | |
| Write-PSFMessage 'No Azure Firewall policies found. Skipping test.' -Tag Firewall -Level Verbose | |
| Add-ZtTestResultDetail -SkippedBecause NotSupported -Description 'No Azure Firewall policies found in any subscription.' |
Copilot
AI
Jan 19, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The output messaging mixes “Deny mode” (test title/check name) with “Alert and Deny mode” (result text/title). Since the pass condition is ThreatIntelMode == 'Deny', consider standardizing the wording throughout (either consistently refer to the Azure enum value 'Deny' or consistently explain it as 'Alert and Deny') to avoid confusing users.
Copilot
AI
Jan 19, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The results table omits Resource Group (and per-policy pass/fail) even though you collect ResourceGroup/Status in $results. Without Resource Group it can be hard to uniquely identify a policy (names can repeat across RGs). Consider adding Resource Group (and optionally Status) columns to the markdown table.
| $mdInfo += "| Check name | Policy name | Subscription name | Subscription id | Threat Intel Mode |`n" | |
| $mdInfo += "| :--- | :--- | :--- | :--- | :---: |`n" | |
| foreach ($item in $results | Sort-Object PolicyName) { | |
| $mdInfo += "| $($item.CheckName) | $($item.PolicyName) | $($item.SubscriptionName) | $($item.SubscriptionId) | $($item.ThreatIntelMode) |`n" | |
| $mdInfo += "| Check name | Policy name | Subscription name | Subscription id | Resource group | Status | Threat Intel Mode |`n" | |
| $mdInfo += "| :--- | :--- | :--- | :--- | :--- | :---: | :---: |`n" | |
| foreach ($item in $results | Sort-Object PolicyName) { | |
| $mdInfo += "| $($item.CheckName) | $($item.PolicyName) | $($item.SubscriptionName) | $($item.SubscriptionId) | $($item.ResourceGroup) | $($item.Status) | $($item.ThreatIntelMode) |`n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description says the check evaluates “the firewall policy attached to the firewall”, but the implementation evaluates all firewall policies in the subscription(s), including potentially unattached policies. Please either update the implementation to scope to policies actually associated with Azure Firewalls, or adjust this documentation to match the implemented scope.