<# .SYNOPSIS Scan an Azure subscription for resources using certificate pinning–related configurations. .NOTES Requires: Az PowerShell modules #> # Login if needed if (-not (Get-AzContext)) { Connect-AzAccount } Write-Host "`n=== Azure Certificate Pinning Scanner ===`n" -ForegroundColor Cyan $subscriptions = Get-AzSubscription foreach ($sub in $subscriptions) { Write-Host "Scanning subscription: $($sub.Name)" -ForegroundColor Yellow Set-AzContext -Subscription $sub.Id | Out-Null # ----------------------------- # 1. App Services & Function Apps # ----------------------------- $webApps = Get-AzWebApp -ErrorAction SilentlyContinue foreach ($app in $webApps) { $config = Get-AzWebApp -ResourceGroupName $app.ResourceGroup -Name $app.Name # Look for root certificate loading (common for pinning) if ($config.SiteConfig.AppSettings.Value -contains "WEBSITE_LOAD_ROOT_CERTIFICATES") { Write-Host "[AppService] $($app.Name) uses WEBSITE_LOAD_ROOT_CERTIFICATES" -ForegroundColor Green } # Look for uploaded certificates $certSettings = Get-AzWebAppCertificate -ResourceGroupName $app.ResourceGroup -WebAppName $app.Name -ErrorAction SilentlyContinue if ($certSettings) { Write-Host "[AppService] $($app.Name) contains uploaded certificates (possible pinning)" -ForegroundColor Green } # Check app settings for KeyVault cert references foreach ($setting in $config.SiteConfig.AppSettings) { if ($setting.Value -match "vault.azure.net" -and $setting.Value -match "secrets") { Write-Host "[AppService] $($app.Name) references a Key Vault cert/secret: $($setting.Name)" -ForegroundColor Green } } } # ----------------------------- # 2. API Management – Backend cert validation # ----------------------------- $apims = Get-AzApiManagement -ErrorAction SilentlyContinue foreach ($apim in $apims) { $backends = Get-AzApiManagementBackend -Context $apim foreach ($b in $backends) { if ($b.Tls.ValidateCertificateChain -eq $true -or $b.Tls.ValidateCertificateName -eq $true) { Write-Host "[APIM] Backend '$($b.Name)' uses strict TLS validation (possible pinning)" -ForegroundColor Green } if ($b.Tls.Certificate) { Write-Host "[APIM] Backend '$($b.Name)' uses custom client certificates" -ForegroundColor Green } } # Custom domains (client certificate requirement) $domains = Get-AzApiManagementCustomHostname -Context $apim foreach ($d in $domains) { if ($d.Certificate) { Write-Host "[APIM] Custom domain '$($d.Hostname)' uses uploaded certificate" -ForegroundColor Green } } } # ----------------------------- # 3. Application Gateway – Trusted Root Certificates # ----------------------------- $agws = Get-AzApplicationGateway -ErrorAction SilentlyContinue foreach ($agw in $agws) { foreach ($cert in $agw.TrustedRootCertificates) { Write-Host "[AppGateway] Trusted root cert present: $($cert.Name)" -ForegroundColor Green } foreach ($httpSetting in $agw.BackendHttpSettingsCollection) { if ($httpSetting.TrustedRootCertificates) { Write-Host "[AppGateway] Backend setting '$($httpSetting.Name)' pins a root certificate" -ForegroundColor Green } } } # ----------------------------- # 4. Azure Front Door (Standard/Premium) – Backend trusted roots # ----------------------------- $afds = Get-AzFrontDoorCdnProfile -ErrorAction SilentlyContinue foreach ($afd in $afds) { $endpoints = Get-AzFrontDoorCdnEndpoint -ProfileName $afd.Name -ResourceGroupName $afd.ResourceGroup foreach ($ep in $endpoints) { $origins = Get-AzFrontDoorCdnOrigin -ResourceGroupName $afd.ResourceGroup -ProfileName $afd.Name -EndpointName $ep.Name foreach ($origin in $origins) { if ($origin.OriginCertificate) { Write-Host "[FrontDoor] Origin '$($origin.Name)' uses custom cert validation" -ForegroundColor Green } } } } } Write-Host "`nScan completed.`n" -ForegroundColor Cyan