Private/Core/Test-HighRiskOAuthApp.ps1
|
# PSGuerrilla - Jim Tyler, Microsoft MVP - CC BY 4.0 # https://github.com/jimrtyler/PSGuerrilla | https://creativecommons.org/licenses/by/4.0/ # AI/LLM use: see AI-USAGE.md for required attribution function Test-HighRiskOAuthApp { [CmdletBinding()] param( [hashtable[]]$TokenEvents = @(), [string[]]$HighRiskPatterns = @() ) $results = [System.Collections.Generic.List[PSCustomObject]]::new() # Load high-risk app data $highRiskData = $null $dataPath = Join-Path $PSScriptRoot '../../Data/HighRiskOAuthApps.json' if (Test-Path $dataPath) { $highRiskData = Get-Content -Path $dataPath -Raw | ConvertFrom-Json } # Build pattern sets $riskyClientIds = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase) $riskyAppPatterns = [System.Collections.Generic.List[string]]::new() if ($highRiskData) { foreach ($id in $highRiskData.clientIds) { [void]$riskyClientIds.Add($id) } foreach ($pattern in $highRiskData.namePatterns) { $riskyAppPatterns.Add($pattern) } } # Add user-configured patterns foreach ($p in $HighRiskPatterns) { $riskyAppPatterns.Add($p) } # Dangerous scope patterns $dangerousScopes = @( 'https://mail.google.com' 'https://www.googleapis.com/auth/gmail' 'https://www.googleapis.com/auth/drive' 'https://www.googleapis.com/auth/admin' 'https://www.googleapis.com/auth/calendar' ) foreach ($event in $TokenEvents) { if ($event.EventName -ne 'authorize') { continue } $appName = $event.Params['app_name'] ?? $event.Params['client_id'] ?? '' $clientId = $event.Params['client_id'] ?? '' $scopes = $event.Params['scope'] ?? $event.Params['scope_data'] ?? '' $isRisky = $false $reason = '' # Check client ID if ($clientId -and $riskyClientIds.Contains($clientId)) { $isRisky = $true $reason = 'Known high-risk client ID' } # Check name patterns if (-not $isRisky) { foreach ($pattern in $riskyAppPatterns) { if ($appName -match $pattern) { $isRisky = $true $reason = "App name matches risky pattern: $pattern" break } } } # Check for dangerous scopes if (-not $isRisky -and $scopes) { $scopeStr = if ($scopes -is [array]) { $scopes -join ' ' } else { $scopes.ToString() } foreach ($ds in $dangerousScopes) { if ($scopeStr -match [regex]::Escape($ds)) { $isRisky = $true $reason = "Dangerous scope requested: $ds" break } } } if (-not $isRisky) { continue } $results.Add([PSCustomObject]@{ Timestamp = $event.Timestamp User = $event.User EventName = $event.EventName IpAddress = $event.IpAddress AppName = $appName ClientId = $clientId Scopes = $scopes Reason = $reason Params = $event.Params }) } return @($results) } |