Skip to content

Commit cb6cc13

Browse files
Network - 27000 - Code improvements (#1049)
* default action to 'unknown' when it does not exist to treat category as not blocked * early exit when only default policy(All websites) exists * moved per category block status evaluation to helper function * updating title * Fix typo in error message comment --------- Co-authored-by: Aleksandar Nikolić <alexandair@live.com>
1 parent ce116eb commit cb6cc13

1 file changed

Lines changed: 156 additions & 97 deletions

File tree

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

Lines changed: 156 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function Test-Assessment-27000 {
2424
SfiPillar = 'Protect networks',
2525
TenantType = ('Workforce'),
2626
TestId = 27000,
27-
Title = 'High-risk WCF categories (Criminal activity, Hacking, Illegal software) are blocked',
27+
Title = 'Web content filtering blocks high-risk categories',
2828
UserImpact = 'Low'
2929
)]
3030
[CmdletBinding()]
@@ -55,6 +55,141 @@ function Test-Assessment-27000 {
5555
}
5656
return $results
5757
}
58+
59+
function Get-CategoryBlockStatus {
60+
<#
61+
.SYNOPSIS
62+
Evaluates whether a specific WCF category is blocked through an effective profile.
63+
64+
.DESCRIPTION
65+
Finds policies covering the category, identifies linked profiles, and determines
66+
the effective profile based on priority and CA enforcement criteria.
67+
#>
68+
param(
69+
[Parameter(Mandatory)]
70+
[string]$CategoryName,
71+
72+
[Parameter(Mandatory)]
73+
[string]$CategoryDisplayName,
74+
75+
[Parameter(Mandatory)]
76+
[array]$FilteringPolicies,
77+
78+
[Parameter(Mandatory)]
79+
[array]$FilteringProfiles,
80+
81+
[Parameter(Mandatory)]
82+
[AllowNull()]
83+
[array]$CAPolicies,
84+
85+
[Parameter(Mandatory)]
86+
[int]$BaselinePriority
87+
)
88+
89+
# Find all policies that cover this category
90+
$policiesCoveringCategory = @($FilteringPolicies | Where-Object {
91+
$policy = $_
92+
$webCatRules = @($policy.policyRules | Where-Object { $_.ruleType -eq 'webCategory' })
93+
$webCatRules | Where-Object {
94+
$_.destinations | Where-Object { $_.name -eq $CategoryName }
95+
}
96+
})
97+
98+
# Collect profile candidates from all matching policies
99+
$profileCandidates = @()
100+
foreach ($policy in $policiesCoveringCategory) {
101+
$findParams = @{
102+
PolicyId = $policy.id
103+
FilteringProfiles = $FilteringProfiles
104+
CAPolicies = $CAPolicies
105+
BaselinePriority = $BaselinePriority
106+
PolicyLinkType = 'filteringPolicyLink'
107+
PolicyRules = @($policy.policyRules)
108+
}
109+
$linkedProfiles = Find-ZtProfilesLinkedToPolicy @findParams
110+
111+
foreach ($linkedProfile in $linkedProfiles) {
112+
# Skip disabled profiles
113+
if ($linkedProfile.ProfileState -ne 'enabled') {
114+
Write-PSFMessage "Skipping disabled profile '$($linkedProfile.ProfileName)'" -Level Verbose
115+
continue
116+
}
117+
118+
# Get the profile object to access policies collection
119+
$filteringProfile = $FilteringProfiles | Where-Object { $_.id -eq $linkedProfile.ProfileId }
120+
if (-not $filteringProfile) {
121+
Write-PSFMessage "Profile '$($linkedProfile.ProfileName)' not found in filteringProfiles collection" -Level Warning
122+
continue
123+
}
124+
125+
# Find the policy link to get priority and action
126+
foreach ($policyLink in $filteringProfile.policies) {
127+
if ($policyLink.policy.id -ne $policy.id) { continue }
128+
129+
# Skip disabled policy links
130+
if ($policyLink.state -ne 'enabled') {
131+
Write-PSFMessage "Skipping disabled policy link in profile '$($linkedProfile.ProfileName)' for policy '$($policy.name)'" -Level Verbose
132+
continue
133+
}
134+
135+
$linkPriority = try { [int]$policyLink.priority } catch { [int]::MaxValue }
136+
137+
# Use policy action directly (not overridden at profile level)
138+
$linkAction = if ($policyLink.policy.action) {
139+
$policyLink.policy.action.ToString().ToLower()
140+
}
141+
else {
142+
Write-PSFMessage "Policy action is null for policy '$($policy.name)' - defaulting to 'unknown'" -Level Warning
143+
'unknown'
144+
}
145+
146+
$profileCandidates += [PSCustomObject]@{
147+
ProfileId = $linkedProfile.ProfileId
148+
ProfileName = $linkedProfile.ProfileName
149+
ProfilePriority= $linkedProfile.ProfilePriority
150+
IsBaseline = ($linkedProfile.ProfileType -eq 'Baseline Profile')
151+
PolicyAction = $linkAction
152+
PolicyPriority = $linkPriority
153+
PassesCriteria = $linkedProfile.PassesCriteria
154+
}
155+
}
156+
}
157+
}
158+
159+
# Sort by profile priority, then policy priority
160+
$profileCandidates = @($profileCandidates | Sort-Object ProfilePriority, PolicyPriority)
161+
162+
# Find effective profile per spec logic
163+
$effectiveProfileName = 'None'
164+
$caEnforced = 'N/A'
165+
$status = 'Not blocked'
166+
167+
foreach ($pc in $profileCandidates) {
168+
if ($pc.IsBaseline) {
169+
# Baseline profile is always effective
170+
$effectiveProfileName = $pc.ProfileName
171+
$caEnforced = 'N/A'
172+
$status = if ($pc.PolicyAction -eq 'block') { 'Blocked' } else { 'Not blocked' }
173+
break
174+
}
175+
else {
176+
# Security profile - check if it passes CA enforcement criteria
177+
if ($pc.PassesCriteria) {
178+
$effectiveProfileName = $pc.ProfileName
179+
$caEnforced = 'Yes'
180+
$status = if ($pc.PolicyAction -eq 'block') { 'Blocked' } else { 'Not blocked' }
181+
break
182+
}
183+
}
184+
}
185+
186+
return [PSCustomObject]@{
187+
Category = $CategoryDisplayName
188+
EnforcedBy = $effectiveProfileName
189+
CAEnforced = $caEnforced
190+
Status = $status
191+
}
192+
}
58193
#endregion Helper Functions
59194

60195
#region Data Collection
@@ -106,122 +241,46 @@ function Test-Assessment-27000 {
106241
$categoryResults = @()
107242

108243
if($errorMsg) {
244+
# Error occurred during data collection, cannot proceed with assessment -> Fail
109245
Write-PSFMessage "Error during data collection: $errorMsg" -Level Error
110246
$testResultMarkdown = "❌ Failed to retrieve necessary data for assessment.`n`nError: $errorMsg"
111247
}
112248
elseif(-not $filteringPolicies -or $filteringPolicies.Count -eq 0 ){
113-
Write-PSFMessage "No WCF policies found" -Level Warning
249+
Write-PSFMessage "No WCF policies found -> Fail" -Level Warning
250+
$categoryResults = New-FailedCategoryResults -RequiredCategories $requiredCategories -CategoryDisplayNames $categoryDisplayNames
251+
$blockedCount = 0
252+
$notBlockedCount = $requiredCategories.Count
253+
}
254+
elseif ($filteringPolicies -and $filteringPolicies.count -eq 1 -and $filteringPolicies[0].name -eq 'All Websites'){
255+
Write-PSFMessage "Only default 'All Websites' policy exists -> Fail" -Level Warning
114256
$categoryResults = New-FailedCategoryResults -RequiredCategories $requiredCategories -CategoryDisplayNames $categoryDisplayNames
115257
$blockedCount = 0
116258
$notBlockedCount = $requiredCategories.Count
117259
}
118260
elseif (-not $filteringProfiles -or $filteringProfiles.Count -eq 0) {
119-
Write-PSFMessage "No filtering profiles found" -Level Warning
261+
Write-PSFMessage "No filtering profiles found -> Fail" -Level Warning
120262
$categoryResults = New-FailedCategoryResults -RequiredCategories $requiredCategories -CategoryDisplayNames $categoryDisplayNames
121263
$blockedCount = 0
122264
$notBlockedCount = $requiredCategories.Count
123265
}
124266
else {
125267
[int]$BASELINE_PROFILE_PRIORITY = 65000
126268

127-
# Evaluate each category
269+
# Evaluate each category using the helper function
128270
foreach ($catName in $requiredCategories) {
129271
$catDisplay = $categoryDisplayNames[$catName]
130272

131-
# Find all policies that cover this category using filtering
132-
$policiesCoveringCategory = @($filteringPolicies | Where-Object {
133-
$policy = $_
134-
$webCatRules = @($policy.policyRules | Where-Object { $_.ruleType -eq 'webCategory' })
135-
$webCatRules | Where-Object {
136-
$_.destinations | Where-Object { $_.name -eq $catName }
137-
}
138-
})
139-
140-
# Find all profiles linked to these policies using Find-ZtProfilesLinkedToPolicy
141-
$profileCandidates = @()
142-
foreach ($policy in $policiesCoveringCategory) {
143-
$findParams = @{
144-
PolicyId = $policy.id
145-
FilteringProfiles = $filteringProfiles
146-
CAPolicies = $caPolicies
147-
BaselinePriority = $BASELINE_PROFILE_PRIORITY
148-
PolicyLinkType = 'filteringPolicyLink'
149-
PolicyRules = @($policy.policyRules)
150-
}
151-
$linkedProfiles = Find-ZtProfilesLinkedToPolicy @findParams
152-
153-
# For each linked profile, get the policy link priority and action
154-
foreach ($linkedProfile in $linkedProfiles) {
155-
$filteringProfile = $filteringProfiles | Where-Object { $_.id -eq $linkedProfile.ProfileId }
156-
if (-not $filteringProfile -or $filteringProfile.state -ne 'enabled') { continue }
157-
158-
# Find the policy link and get its priority and action from the expanded policy
159-
foreach ($policyLink in $filteringProfile.policies) {
160-
if ($policyLink.policy.id -ne $policy.id) { continue }
161-
162-
# Skip disabled policy links
163-
if ($policyLink.state -ne 'enabled') {
164-
Write-PSFMessage "Skipping disabled policy link in profile '$($filteringProfile.name)' for policy '$($policy.name)'" -Level Verbose
165-
continue
166-
}
167-
168-
$linkPriority = try { [int]$policyLink.priority } catch { [int]::MaxValue }
169-
170-
# Get action from the expanded policy object
171-
$linkAction = if ($policyLink.policy.action) {
172-
$policyLink.policy.action.ToString().ToLower()
173-
}
174-
else {
175-
# Default to block for WCF policies
176-
'block'
177-
}
178-
179-
$profileCandidates += [PSCustomObject]@{
180-
ProfileId = $linkedProfile.ProfileId
181-
ProfileName = $linkedProfile.ProfileName
182-
ProfilePriority= $linkedProfile.ProfilePriority
183-
IsBaseline = ($linkedProfile.ProfileType -eq 'Baseline Profile')
184-
PolicyAction = $linkAction
185-
PolicyPriority = $linkPriority
186-
PassesCriteria = $linkedProfile.PassesCriteria
187-
}
188-
}
189-
}
190-
}
191-
192-
# Sort by profile priority, then policy priority
193-
$profileCandidates = @($profileCandidates | Sort-Object ProfilePriority, PolicyPriority)
194-
195-
# Find effective profile per spec logic
196-
$effectiveProfileName = 'None'
197-
$caEnforced = 'N/A' # Default to N/A when no profile found
198-
$status = 'Not blocked'
199-
200-
foreach ($pc in $profileCandidates) {
201-
if ($pc.IsBaseline) {
202-
# Baseline profile is always effective
203-
$effectiveProfileName = $pc.ProfileName
204-
$caEnforced = 'N/A'
205-
$status = if ($pc.PolicyAction -eq 'block') { 'Blocked' } else { 'Not blocked' }
206-
break
207-
}
208-
else {
209-
# Security profile - check if it passes CA enforcement criteria
210-
if ($pc.PassesCriteria) {
211-
$effectiveProfileName = $pc.ProfileName
212-
$caEnforced = 'Yes'
213-
$status = if ($pc.PolicyAction -eq 'block') { 'Blocked' } else { 'Not blocked' }
214-
break
215-
}
216-
}
273+
$getCategoryParams = @{
274+
CategoryName = $catName
275+
CategoryDisplayName = $catDisplay
276+
FilteringPolicies = $filteringPolicies
277+
FilteringProfiles = $filteringProfiles
278+
CAPolicies = $caPolicies
279+
BaselinePriority = $BASELINE_PROFILE_PRIORITY
217280
}
218281

219-
$categoryResults += [PSCustomObject]@{
220-
Category = $catDisplay
221-
EnforcedBy = $effectiveProfileName
222-
CAEnforced = $caEnforced
223-
Status = $status
224-
}
282+
$categoryResult = Get-CategoryBlockStatus @getCategoryParams
283+
$categoryResults += $categoryResult
225284
}
226285

227286
# Determine pass/fail
@@ -280,7 +339,7 @@ function Test-Assessment-27000 {
280339

281340
$params = @{
282341
TestId = '27000'
283-
Title = 'High-risk WCF categories (Criminal activity, Hacking, Illegal software) are blocked'
342+
Title = 'Web content filtering blocks high-risk categories'
284343
Status = $passed
285344
Result = $testResultMarkdown
286345
}

0 commit comments

Comments
 (0)