Skip to content

Commit 4c58339

Browse files
committed
feat: Enhance Chrome Extension deployment with domain squatting detection and additional settings
1 parent 9d2e136 commit 4c58339

1 file changed

Lines changed: 54 additions & 11 deletions

File tree

Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDeployCheckChromeExtension.ps1

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@ function Invoke-CIPPStandardDeployCheckChromeExtension {
2828
{"type":"textField","name":"standards.DeployCheckChromeExtension.webhookUrl","label":"Webhook URL","placeholder":"https://webhook.example.com/endpoint","required":false}
2929
{"type":"autoComplete","multiple":true,"creatable":true,"required":false,"label":"Webhook Events","name":"standards.DeployCheckChromeExtension.webhookEvents","placeholder":"e.g. pageBlocked, pageAllowed"}
3030
{"type":"autoComplete","multiple":true,"creatable":true,"required":false,"label":"URL Allowlist","name":"standards.DeployCheckChromeExtension.urlAllowlist","placeholder":"e.g. https://example.com/*"}
31+
{"type":"switch","name":"standards.DeployCheckChromeExtension.domainSquattingEnabled","label":"Enable domain squatting detection","defaultValue":true}
3132
{"type":"textField","name":"standards.DeployCheckChromeExtension.companyName","label":"Company Name","placeholder":"YOUR-COMPANY","required":false}
32-
{"type":"textField","name":"standards.DeployCheckChromeExtension.companyURL","label":"Company URL","placeholder":"https://yourcompany.com","required":false}
3333
{"type":"textField","name":"standards.DeployCheckChromeExtension.productName","label":"Product Name","placeholder":"YOUR-PRODUCT-NAME","required":false}
3434
{"type":"textField","name":"standards.DeployCheckChromeExtension.supportEmail","label":"Support Email","placeholder":"support@yourcompany.com","required":false}
35+
{"type":"textField","name":"standards.DeployCheckChromeExtension.supportUrl","label":"Support URL","placeholder":"https://support.yourcompany.com","required":false}
36+
{"type":"textField","name":"standards.DeployCheckChromeExtension.privacyPolicyUrl","label":"Privacy Policy URL","placeholder":"https://yourcompany.com/privacy","required":false}
37+
{"type":"textField","name":"standards.DeployCheckChromeExtension.aboutUrl","label":"About URL","placeholder":"https://yourcompany.com/about","required":false}
3538
{"type":"textField","name":"standards.DeployCheckChromeExtension.primaryColor","label":"Primary Color","placeholder":"#F77F00","required":false}
3639
{"type":"textField","name":"standards.DeployCheckChromeExtension.logoUrl","label":"Logo URL","placeholder":"https://yourcompany.com/logo.png","required":false}
3740
{"name":"AssignTo","label":"Who should this app be assigned to?","type":"radio","options":[{"label":"Do not assign","value":"On"},{"label":"Assign to all users","value":"allLicensedUsers"},{"label":"Assign to all devices","value":"AllDevices"},{"label":"Assign to all users and devices","value":"AllDevicesAndUsers"},{"label":"Assign to Custom Group","value":"customGroup"}]}
@@ -90,10 +93,13 @@ function Invoke-CIPPStandardDeployCheckChromeExtension {
9093
$WebhookUrl = $Settings.webhookUrl ?? ''
9194
$WebhookEvents = @($Settings.webhookEvents | ForEach-Object { $_.value ?? $_ } | Where-Object { $_ })
9295
$UrlAllowlist = @($Settings.urlAllowlist | ForEach-Object { $_.value ?? $_ } | Where-Object { $_ })
96+
$DomainSquattingEnabled = [int][bool]($Settings.domainSquattingEnabled ?? $true)
9397
$CompanyName = $Settings.companyName ?? ''
94-
$CompanyURL = $Settings.companyURL ?? ''
9598
$ProductName = $Settings.productName ?? ''
9699
$SupportEmail = $Settings.supportEmail ?? ''
100+
$SupportUrl = $Settings.supportUrl ?? ''
101+
$PrivacyPolicyUrl = $Settings.privacyPolicyUrl ?? ''
102+
$AboutUrl = $Settings.aboutUrl ?? ''
97103
$PrimaryColor = if ($Settings.primaryColor) { $Settings.primaryColor } else { '#F77F00' }
98104
$LogoUrl = $Settings.logoUrl ?? ''
99105

@@ -140,13 +146,21 @@ foreach (`$b in `$browsers) {
140146
New-ItemProperty -Path `$b.ManagedStorageKey -Name 'updateInterval' -PropertyType DWord -Value $UpdateInterval -Force | Out-Null
141147
New-ItemProperty -Path `$b.ManagedStorageKey -Name 'enableDebugLogging' -PropertyType DWord -Value $EnableDebugLogging -Force | Out-Null
142148
149+
# Managed storage - domainSquatting subkey
150+
`$domainSquattingKey = "`$(`$b.ManagedStorageKey)\domainSquatting"
151+
if (!(Test-Path `$domainSquattingKey)) { New-Item -Path `$domainSquattingKey -Force | Out-Null }
152+
New-ItemProperty -Path `$domainSquattingKey -Name 'enabled' -PropertyType DWord -Value $DomainSquattingEnabled -Force | Out-Null
153+
143154
# Managed storage - customBranding subkey
144155
`$brandingKey = "`$(`$b.ManagedStorageKey)\customBranding"
145156
if (!(Test-Path `$brandingKey)) { New-Item -Path `$brandingKey -Force | Out-Null }
146157
New-ItemProperty -Path `$brandingKey -Name 'companyName' -PropertyType String -Value '$($CompanyName -replace "'", "''")' -Force | Out-Null
147-
New-ItemProperty -Path `$brandingKey -Name 'companyURL' -PropertyType String -Value '$($CompanyURL -replace "'", "''")' -Force | Out-Null
158+
148159
New-ItemProperty -Path `$brandingKey -Name 'productName' -PropertyType String -Value '$($ProductName -replace "'", "''")' -Force | Out-Null
149-
New-ItemProperty -Path `$brandingKey -Name 'supportEmail' -PropertyType String -Value '$($SupportEmail -replace "'", "''")' -Force | Out-Null
160+
New-ItemProperty -Path `$brandingKey -Name 'supportEmail' -PropertyType String -Value '$($SupportEmail -replace "'", "''")' -Force | Out-Null
161+
New-ItemProperty -Path `$brandingKey -Name 'supportUrl' -PropertyType String -Value '$($SupportUrl -replace "'", "''")' -Force | Out-Null
162+
New-ItemProperty -Path `$brandingKey -Name 'privacyPolicyUrl' -PropertyType String -Value '$($PrivacyPolicyUrl -replace "'", "''")' -Force | Out-Null
163+
New-ItemProperty -Path `$brandingKey -Name 'aboutUrl' -PropertyType String -Value '$($AboutUrl -replace "'", "''")' -Force | Out-Null
150164
New-ItemProperty -Path `$brandingKey -Name 'primaryColor' -PropertyType String -Value '$PrimaryColor' -Force | Out-Null
151165
New-ItemProperty -Path `$brandingKey -Name 'logoUrl' -PropertyType String -Value '$($LogoUrl -replace "'", "''")' -Force | Out-Null
152166
@@ -251,13 +265,21 @@ foreach (`$key in @(`$chromeKey, `$edgeKey)) {
251265
if (!(Test-RegValue `$key 'cippTenantId' '$CippTenantId')) { exit 1 }
252266
if (!(Test-RegValue `$key 'customRulesUrl' '$CustomRulesUrl')) { exit 1 }
253267
268+
# domainSquatting subkey
269+
`$domainSquattingKey = "`$key\domainSquatting"
270+
if (!(Test-Path `$domainSquattingKey)) { exit 1 }
271+
if (!(Test-RegValue `$domainSquattingKey 'enabled' $DomainSquattingEnabled)) { exit 1 }
272+
254273
# customBranding subkey
255274
`$brandingKey = "`$key\customBranding"
256275
if (!(Test-Path `$brandingKey)) { exit 1 }
257276
if (!(Test-RegValue `$brandingKey 'companyName' '$($CompanyName -replace "'", "''")')) { exit 1 }
258-
if (!(Test-RegValue `$brandingKey 'companyURL' '$($CompanyURL -replace "'", "''")')) { exit 1 }
277+
259278
if (!(Test-RegValue `$brandingKey 'productName' '$($ProductName -replace "'", "''")')) { exit 1 }
260-
if (!(Test-RegValue `$brandingKey 'supportEmail' '$($SupportEmail -replace "'", "''")')) { exit 1 }
279+
if (!(Test-RegValue `$brandingKey 'supportEmail' '$($SupportEmail -replace "'", "''")')) { exit 1 }
280+
if (!(Test-RegValue `$brandingKey 'supportUrl' '$($SupportUrl -replace "'", "''")')) { exit 1 }
281+
if (!(Test-RegValue `$brandingKey 'privacyPolicyUrl' '$($PrivacyPolicyUrl -replace "'", "''")')) { exit 1 }
282+
if (!(Test-RegValue `$brandingKey 'aboutUrl' '$($AboutUrl -replace "'", "''")')) { exit 1 }
261283
if (!(Test-RegValue `$brandingKey 'primaryColor' '$PrimaryColor')) { exit 1 }
262284
if (!(Test-RegValue `$brandingKey 'logoUrl' '$($LogoUrl -replace "'", "''")')) { exit 1 }
263285
@@ -312,6 +334,16 @@ Write-Output 'Check Chrome Extension is correctly configured.'
312334
exit 0
313335
"@
314336

337+
##########################################################################
338+
# Compute a settings fingerprint from the install script so we can skip
339+
# redeploy when nothing has changed.
340+
##########################################################################
341+
$Sha256 = [System.Security.Cryptography.SHA256]::Create()
342+
$SettingsHash = ([System.BitConverter]::ToString(
343+
$Sha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($InstallScript))
344+
) -replace '-', '').Substring(0, 16)
345+
$AppDescription = "Deploys and configures the Check by CyberDrain phishing protection extension for Chrome and Edge browsers. Managed by CIPP. [cfg:$SettingsHash]"
346+
315347
##########################################################################
316348
# Legacy OMA-URI policy cleanup
317349
##########################################################################
@@ -325,7 +357,7 @@ exit 0
325357
# Check for existing Win32 app
326358
##########################################################################
327359
$Baseuri = 'https://graph.microsoft.com/beta/deviceAppManagement/mobileApps'
328-
$ExistingApps = New-GraphGetRequest -Uri "$Baseuri`?`$filter=displayName eq '$AppDisplayName'&`$select=id,displayName" -tenantid $Tenant | Where-Object {
360+
$ExistingApps = New-GraphGetRequest -Uri "$Baseuri`?`$filter=displayName eq '$AppDisplayName'&`$select=id,displayName,description" -tenantid $Tenant | Where-Object {
329361
$_.'@odata.type' -eq '#microsoft.graph.win32LobApp'
330362
}
331363
$AppExists = ($null -ne $ExistingApps -and @($ExistingApps).Count -gt 0)
@@ -358,9 +390,20 @@ exit 0
358390
}
359391

360392
if ($AppExists) {
361-
# App exists — delete and recreate to pick up any script changes
362-
foreach ($ExistingApp in @($ExistingApps)) {
363-
$null = New-GraphPostRequest -Uri "$Baseuri/$($ExistingApp.id)" -Type DELETE -tenantid $Tenant
393+
# Check if the settings hash matches — skip redeploy if nothing changed
394+
$ExistingHash = $null
395+
$ExistingApp = @($ExistingApps)[0]
396+
if ($ExistingApp.description -match '\[cfg:([0-9A-Fa-f]{16})\]') {
397+
$ExistingHash = $Matches[1]
398+
}
399+
400+
if ($ExistingHash -eq $SettingsHash) {
401+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "$AppDisplayName settings unchanged — skipping redeploy" -sev Info
402+
return
403+
}
404+
405+
foreach ($App in @($ExistingApps)) {
406+
$null = New-GraphPostRequest -Uri "$Baseuri/$($App.id)" -Type DELETE -tenantid $Tenant
364407
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Removed existing $AppDisplayName app to redeploy with updated settings" -sev Info
365408
}
366409
Start-Sleep -Seconds 2
@@ -369,7 +412,7 @@ exit 0
369412
# Deploy the Win32 script app
370413
$AppProperties = [PSCustomObject]@{
371414
displayName = $AppDisplayName
372-
description = 'Deploys and configures the Check by CyberDrain phishing protection extension for Chrome and Edge browsers. Managed by CIPP.'
415+
description = $AppDescription
373416
publisher = 'CIPP'
374417
installScript = $InstallScript
375418
uninstallScript = $UninstallScript

0 commit comments

Comments
 (0)