Created
November 26, 2025 06:29
-
-
Save JeffWouters/52ddc5809dd6962ae899e8ba112e1349 to your computer and use it in GitHub Desktop.
Azure - Scan for pinned certificates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| .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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment