tests/Test-Assessment.25416.ps1
|
<#
.SYNOPSIS Branch office internet traffic is protected by Cloud Firewall policies through Global Secure Access .DESCRIPTION Evaluates whether branch office internet traffic is protected by cloud firewall policies through Global Secure Access. Without cloud firewall policies enforced on remote network traffic, branch office internet traffic flows through Global Secure Access without egress filtering, exposing the organization to data exfiltration, command-and-control communications, and malicious outbound connections from compromised branch assets. .NOTES Test ID: 25416 Pillar: Network Risk Level: High SFI Pillar: Protect networks #> function Test-Assessment-25416 { [ZtTest( Category = 'Global Secure Access', ImplementationCost = 'Medium', MinimumLicense = ('Entra_Premium_Internet_Access'), Pillar = 'Network', RiskLevel = 'High', SfiPillar = 'Protect networks', TenantType = ('Workforce', 'External'), TestId = '25416', Title = 'Branch office internet traffic is protected by Cloud Firewall policies through Global Secure Access', UserImpact = 'Low' )] [CmdletBinding()] param() # Define constants [int]$BASELINE_PROFILE_PRIORITY = 65000 #region Data Collection Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose $activity = 'Checking Branch office internet traffic is protected by Cloud Firewall policies through Global Secure Access' Write-ZtProgress -Activity $activity -Status 'Querying remote networks' # Q1: Get all configured remote networks (branch sites) $remoteNetworks = Invoke-ZtGraphRequest -RelativeUri 'networkAccess/connectivity/branches' -ApiVersion beta $remoteNetworkCount = if ($remoteNetworks) { $remoteNetworks.Count } else { 0 } # If Q1 returns no remote networks → Skipped if ($remoteNetworkCount -eq 0) { Write-PSFMessage 'No remote networks are configured. Cloud Firewall policies for remote networks are not applicable.' -Tag Test -Level Verbose Add-ZtTestResultDetail -SkippedBecause NotApplicable return } # Q2: Get filtering profiles with cloud firewall policy links $baselineProfileWithCloudFirewall = @() Write-ZtProgress -Activity $activity -Status 'Querying baseline security profile' $filteringProfiles = Invoke-ZtGraphRequest -RelativeUri 'networkAccess/filteringProfiles' -QueryParameters @{ '$select' = 'id,name,description,state,version,priority' '$expand' = 'policies($select=id,state;$expand=policy)' } -ApiVersion beta if ($filteringProfiles -and $remoteNetworkCount -gt 0) { $baselineProfile = $filteringProfiles | Where-Object { $_.priority -eq $BASELINE_PROFILE_PRIORITY } if ($null -ne $baselineProfile -and $null -ne $baselineProfile.policies) { # Check if baseline profile has enabled cloud firewall policy links $enabledCloudFirewallPolicies = @() $policyLinks = $baselineProfile.policies | Where-Object { $_.'@odata.type' -eq '#microsoft.graph.networkAccess.cloudFirewallPolicyLink' } # Iterate over each cloud firewall policy link foreach ($policyLink in $policyLinks) { # Q3: Retrieve the actual cloud firewall policy rules using policy.id $policyId = if ($policyLink.policy) { $policyLink.policy.id } else { $null } $policyRulesData = @() $enabledRulesCount = 0 if ($policyId) { $policyDisplayName = if ($policyLink.policy.name) { $policyLink.policy.name } else { 'Unknown' } Write-ZtProgress -Activity $activity -Status "Retrieving policy rules for $policyDisplayName" try { # Q3: GET https://graph.microsoft.com/beta/networkAccess/cloudfirewallpolicies/{policyId}?$expand=policyRules $policyWithRules = Invoke-ZtGraphRequest -RelativeUri "networkAccess/cloudfirewallpolicies/$policyId" -QueryParameters @{ '$expand' = 'policyRules' } -ApiVersion beta if ($policyWithRules -and $policyWithRules.policyRules) { $policyRulesData = $policyWithRules.policyRules # Count enabled rules where settings.status = 'enabled' $enabledRulesCount = ($policyRulesData | Where-Object { $_.settings.status -eq 'enabled' }).Count } } catch { Write-PSFMessage "Error retrieving policy rules for policy $policyId`: $_" -Tag Test -Level Warning } } $enabledCloudFirewallPolicies += [PSCustomObject]@{ PolicyLinkId = $policyLink.id PolicyLinkState = $policyLink.state PolicyId = $policyId PolicyName = if ($policyLink.policy) { $policyLink.policy.name } else { 'Unknown' } PolicyRules = $policyRulesData TotalRulesCount = $policyRulesData.Count EnabledRulesCount = $enabledRulesCount } } if ($enabledCloudFirewallPolicies.Count -gt 0) { # Create an array with one object per cloud firewall policy foreach ($cloudFirewallPolicy in $enabledCloudFirewallPolicies) { $baselineProfileWithCloudFirewall += [PSCustomObject]@{ ProfileId = $baselineProfile.id ProfileName = $baselineProfile.name ProfileState = $baselineProfile.state ProfilePriority = $baselineProfile.priority PolicyLinkId = $cloudFirewallPolicy.PolicyLinkId PolicyLinkState = $cloudFirewallPolicy.PolicyLinkState PolicyId = $cloudFirewallPolicy.PolicyId PolicyName = $cloudFirewallPolicy.PolicyName PolicyRules = $cloudFirewallPolicy.PolicyRules TotalRulesCount = $cloudFirewallPolicy.TotalRulesCount EnabledRulesCount = $cloudFirewallPolicy.EnabledRulesCount } } } } } #endregion Data Collection #region Assessment Logic $passed = $false # If Q2 baseline profile has no linked cloud firewall policies OR all linked cloud firewall policies have state="disabled" → Fail if ($baselineProfileWithCloudFirewall.Count -eq 0) { $passed = $false } else { # Check if at least one policy has state="enabled" $enabledPolicies = $baselineProfileWithCloudFirewall | Where-Object { $_.PolicyLinkState -eq 'enabled' } if ($enabledPolicies.Count -eq 0) { # All linked cloud firewall policies have state="disabled" → Fail $passed = $false } else { # Check Q3: If no rules OR all rules have settings.status="disabled" → Fail # If at least one enabled policy has at least one enabled rule → Pass $hasEnabledRules = ($enabledPolicies | Where-Object { $_.EnabledRulesCount -gt 0 }).Count -gt 0 $passed = $hasEnabledRules } } #endregion Assessment Logic #region Report Generation $mdInfo = '' if ($passed) { $testResultMarkdown = "Cloud Firewall is enabled and configured for remote networks. Branch office internet traffic is protected by firewall policies through the baseline security profile.`n`n%TestResult%" } else { $testResultMarkdown = "Cloud Firewall is not properly configured for remote networks. Remote network internet traffic is not protected by cloud firewall policies.`n`n%TestResult%" } # Build remote network table rows $remoteNetworkTableRows = '' $totalEnabledRulesCount = 0 $enabledPoliciesCount = 0 if ($baselineProfileWithCloudFirewall.Count -gt 0) { $totalEnabledRulesCount = ($baselineProfileWithCloudFirewall | Measure-Object -Property EnabledRulesCount -Sum).Sum $enabledPoliciesCount = ($baselineProfileWithCloudFirewall | Where-Object { $_.PolicyLinkState -eq 'enabled' }).Count } foreach ($network in $remoteNetworks | Sort-Object -Property name) { $networkName = Get-SafeMarkdown -Text $network.name $encodedNetworkName = [System.Uri]::EscapeDataString($network.name) $networkPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditBranchMenuBlade.MenuView/~/basics/branchId/$($network.id)/title/$encodedNetworkName/defaultMenuItemId/Basics" $policyLinked = if ($baselineProfileWithCloudFirewall.Count -gt 0) { 'Yes' } else { 'No' } $policyState = if ($enabledPoliciesCount -gt 0) { '✅ Enabled' } elseif ($baselineProfileWithCloudFirewall.Count -gt 0) { '❌ Disabled' } else { 'N/A' } $rulesCount = if ($baselineProfileWithCloudFirewall.Count -gt 0) { $totalEnabledRulesCount } else { 0 } $remoteNetworkTableRows += "| [$networkName]($networkPortalLink) | $policyLinked | $policyState | $rulesCount |`n" } $remoteNetworkTemplate = @" ## Cloud Firewall Configuration for Remote Networks | Remote Network Name | Baseline Profile Policy Linked | Policy State | Rules Configured | | :--- | :--- | :--- | :--- | {0} "@ $mdInfo += $remoteNetworkTemplate -f $remoteNetworkTableRows # Build baseline profile table if ($baselineProfileWithCloudFirewall.Count -gt 0) { $baselineProfileTableRows = '' foreach ($policyEntry in $baselineProfileWithCloudFirewall) { $profileName = Get-SafeMarkdown -Text $policyEntry.ProfileName $profilePriority = $policyEntry.ProfilePriority $policyName = Get-SafeMarkdown -Text $policyEntry.PolicyName $policyState = if ($policyEntry.PolicyLinkState -eq 'enabled') { '✅ Enabled' } else { '❌ Disabled' } $enabledRulesCount = $policyEntry.EnabledRulesCount $baselineProfileTableRows += "| $profileName | $profilePriority | $policyName | $policyState | $enabledRulesCount |`n" } $baselineProfileTemplate = @" ## Baseline Profile Details | Profile Name | Priority | Linked Policy Name | Policy State | Enabled Rules Count | | :--- | :--- | :--- | :--- | :--- | {0} "@ $mdInfo += $baselineProfileTemplate -f $baselineProfileTableRows } else { $mdInfo += "`n## Baseline Profile Details`n`nNo baseline profile with cloud firewall policies configured.`n" } $mdInfo += "`n**Total Remote Networks:** $remoteNetworkCount`n" $testResultMarkdown = $testResultMarkdown -replace '%TestResult%', $mdInfo #endregion Report Generation $params = @{ TestId = '25416' Title = 'Branch office internet traffic is protected by Cloud Firewall policies through Global Secure Access' Status = $passed Result = $testResultMarkdown } Add-ZtTestResultDetail @params } |