The breach at British online retailer ASOS is the latest proof point for a pattern we've been tracking across IR engagements for the past two years: attackers are no longer kicking down the front door — they're logging in. In this incident, a customer-facing SaaS application served as the entry point, and the compromise of a single identity became the beachhead for significantly deeper penetration into the corporate environment.
This is not a novel technique, but the ASOS case matters because it strips away any remaining illusion that SaaS platforms sitting outside your perimeter are somehow outside your threat model. Customer-facing SaaS applications — CRM portals, e-commerce backends, support ticketing systems, marketing automation platforms — hold valid credentials, OAuth tokens, API keys, and trusted integrations into your core environment. When an attacker compromises one identity in that layer, they inherit every trust relationship that identity carries.
For defenders, the lesson is blunt: your SaaS attack surface is your network's attack surface. If your detections stop at the endpoint and your firewall, you have a blind spot exactly where attackers are now focusing their effort.
Technical Analysis
The Attack Pattern
While the full forensic details of the ASOS intrusion continue to emerge, the reported attack chain follows the identity-first SaaS intrusion pattern we consistently observe in 2025–2026 engagements:
- Initial access via a customer-facing SaaS identity. This typically means credential phishing, MFA fatigue (push bombing), adversary-in-the-middle (AiTM) phishing to steal session cookies, or exploitation of weak/legacy authentication on a SaaS tenant.
- Session/token abuse. Rather than using the password, attackers replay stolen session tokens or refresh tokens — bypassing MFA entirely because the token is already post-authentication.
- Privilege and persistence expansion inside the SaaS layer. Attackers register malicious OAuth applications, grant consent to high-scope API permissions, or create additional API keys/service accounts to survive password resets.
- Pivot into the corporate network. The SaaS platform's trusted integrations — SSO into the IdP, synced directories, connected email, CI/CD webhooks, support tooling with remote-access capability — become the lateral movement highway. A single compromised identity with broad SaaS integrations can translate into access to email, document stores, and ultimately internal systems.
Why This Works
The core weakness is implicit trust between identity and integration. Most organizations:
- Treat SaaS sign-ins as low-risk compared to VPN or RDP access
- Allow user-level OAuth consent, letting any user grant third-party apps access to mail, files, and directory data
- Do not monitor SaaS audit logs in the SIEM — or ingest them at all
- Do not revoke session tokens during incident response, only passwords
- Apply conditional access policies to corporate apps but exempt 'low-risk' customer-facing platforms
No CVE is associated with this incident — there is no patch to apply. The vulnerability is architectural: identity sprawl, token-based trust, and unmonitored SaaS telemetry.
Exploitation Status
This is a confirmed, actively exploited intrusion pattern — not theoretical. Identity-based attacks against SaaS platforms have been the dominant initial-access vector in the incidents our team has responded to since early 2025, and the ASOS breach is a public confirmation that retail and e-commerce organizations are squarely in scope. Any organization running customer-facing SaaS with corporate integrations should treat this as a 'patch Tuesday' moment for their identity architecture.
Detection & Response
The detections below target the observable behaviors in this attack chain: anomalous SaaS/IdP sign-ins, malicious OAuth consent, and endpoint session-token theft. All are grounded in techniques we've validated in real investigations — not hypothetical IOCs.
Sigma Rules
---
title: Suspicious OAuth Application Consent Grant
id: 3f8a2b14-6c1d-4e92-b7a5-9d0e1f2a3b4c
status: experimental
description: Detects user or admin consent granted to OAuth applications with high-risk permission scopes, a common persistence technique following SaaS identity compromise.
references:
- https://attack.mitre.org/techniques/T1528/
- https://attack.mitre.org/techniques/T1550/001/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.persistence
- attack.t1528
logsource:
product: azure
service: auditlogs
detection:
selection:
operationName: 'Consent to application'
filter_high_risk_scopes:
targetResources|contains:
- 'Mail.Read'
- 'Mail.Send'
- 'Files.ReadWrite.All'
- 'Directory.ReadWrite.All'
- 'offline_access'
condition: selection and filter_high_risk_scopes
falsepositives:
- Legitimate enterprise app onboarding — maintain an allowlist of approved app IDs
level: high
---
title: Session Token Access to Browser Credential Stores
id: 8c4d1e67-2a9b-4f35-cd80-1e2f3a4b5c6d
status: experimental
description: Detects non-browser processes accessing browser cookie and credential stores, indicative of session token theft used to hijack SaaS identities without a password or MFA prompt.
references:
- https://attack.mitre.org/techniques/T1539/
- https://attack.mitre.org/techniques/T1555/003/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.credential_access
- attack.t1539
- attack.t1555.003
logsource:
category: file_access
product: windows
detection:
selection_path:
TargetFilename|contains:
- '\AppData\Local\Google\Chrome\User Data\Default\Cookies'
- '\AppData\Local\Google\Chrome\User Data\Default\Network\Cookies'
- '\AppData\Local\Microsoft\Edge\User Data\Default\Cookies'
- '\AppData\Local\Microsoft\Edge\User Data\Default\Network\Cookies'
- '\AppData\Roaming\Mozilla\Firefox\Profiles\'
filter_browsers:
Image|endswith:
- '\chrome.exe'
- '\msedge.exe'
- '\firefox.exe'
- '\MsMpEng.exe'
condition: selection_path and not filter_browsers
falsepositives:
- EDR/AV scans — tune per your tooling's process paths
- Backup agents accessing user profiles
level: high
KQL — Microsoft Sentinel / Defender
The first query hunts impossible-travel and token-replay indicators against Entra ID sign-in logs; the second correlates new OAuth consent events with sign-ins from unfamiliar locations in the preceding 24 hours.
// Hunt 1: Impossible travel / token replay indicators in Entra sign-ins
let lookback = 7d;
SigninLogs
| where TimeGenerated > ago(lookback)
| where ResultType == 0
| summarize Locations = make_set(Location), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated),
IPAddresses = make_set(IPAddress), AuthMethods = make_set(AuthenticationRequirement)
by UserPrincipalName, AppDisplayName, bin(TimeGenerated, 1h)
| where array_length(Locations) > 1
| where array_length(IPAddresses) > 2
| project TimeGenerated, UserPrincipalName, AppDisplayName, Locations, IPAddresses, AuthMethods
| order by TimeGenerated desc;
// Hunt 2: OAuth consent grants preceded by sign-in from a new ASN/country
let NewConsent = AuditLogs
| where TimeGenerated > ago(24h)
| where OperationName == 'Consent to application'
| mv-expand TargetResources
| extend AppId = tostring(TargetResources.id)
| extend Scopes = tostring(TargetResources.modifiedProperties)
| where Scopes has_any ('Mail.Read','Mail.Send','Files.ReadWrite','Directory.ReadWrite','offline_access')
| project ConsentTime = TimeGenerated, UserPrincipalName = tostring(InitiatedBy.user.userPrincipalName), AppId, Scopes, IPAddress = tostring(InitiatedBy.user.ipAddress);
let BaselineCountries = SigninLogs
| where TimeGenerated > ago(30d) and TimeGenerated < ago(1d)
| summarize by UserPrincipalName, Location;
NewConsent
| join kind=inner (SigninLogs | where TimeGenerated > ago(24h) | project UserPrincipalName, SignInLocation = Location, SignInIP = IPAddress, SignInTime = TimeGenerated) on UserPrincipalName
| join kind=leftanti BaselineCountries on UserPrincipalName, $left.SignInLocation == $right.Location
| project ConsentTime, UserPrincipalName, AppId, Scopes, SignInLocation, SignInIP;
// Hunt 3 (Defender XDR): Non-browser processes touching browser cookie stores
DeviceFileEvents
| where TimeGenerated > ago(7d)
| where FileName has_any ('Cookies','Login Data','Local State')
| where FolderPath has_any ('\Chrome\User Data\','\Edge\User Data\','\Firefox\Profiles\')
| where InitiatingProcessFileName !in~ ('chrome.exe','msedge.exe','firefox.exe','MsMpEng.exe','MsSense.exe')
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, FolderPath, AccountName
| order by TimeGenerated desc;
Velociraptor VQL
Use this artifact across your Windows fleet to identify processes with open handles to browser credential stores — the telltale sign of session-token theft preceding SaaS identity abuse.
-- Hunt for non-browser processes accessing browser cookie/credential stores
SELECT Pid,
Name AS ProcessName,
Exe AS ProcessPath,
CommandLine,
Username,
CreateTime
FROM pslist()
WHERE CommandLine =~ '(?i)(cookies|login data|local state|\\User Data\\)'
AND Name !~ '(?i)(chrome|msedge|firefox|msmpeng|mssense)'
-- Also enumerate cookie store files with recent modification (potential staging for theft)
SELECT FullPath,
Size AS FileSize,
Mtime AS ModifiedTime
FROM glob(globs='C:\\Users\\*\\AppData\\Local\\*\\*\\User Data\\Default\\Network\\Cookies')
WHERE Mtime > now() - 86400
Remediation & Hardening Script
Run the following from an administrative workstation with the Microsoft Graph PowerShell SDK (Install-Module Microsoft.Graph) to contain a suspected SaaS identity compromise: revoke all active sessions and refresh tokens (a password reset alone does NOT kill stolen tokens), enumerate risky OAuth consent grants, and flag accounts requiring immediate investigation.
# Connect with scopes required for identity containment
Connect-MgGraph -Scopes 'User.ReadWrite.All','Directory.Read.All','Application.Read.All','AuditLog.Read.All' -NoWelcome
# === STEP 1: Revoke all sessions/refresh tokens for the compromised identity ===
# Replace with the UPN of the suspected compromised account
$TargetUser = 'compromised.user@yourdomain.com'
Revoke-MgUserSignInSession -UserId $TargetUser
Write-Host "[+] Sessions and refresh tokens revoked for $TargetUser" -ForegroundColor Green
# === STEP 2: Force password reset on next sign-in ===
$PasswordProfile = @{ ForceChangePasswordNextSignIn = $true; ForceChangePasswordNextSignInWithMfa = $true }
Update-MgUser -UserId $TargetUser -PasswordProfile $PasswordProfile
Write-Host "[+] Forced password reset with MFA re-registration set for $TargetUser" -ForegroundColor Green
# === STEP 3: Enumerate OAuth consent grants with high-risk scopes ===
$HighRiskScopes = 'Mail.Read','Mail.Send','Files.ReadWrite.All','Directory.ReadWrite.All','offline_access','full_access_as_app'
$Grants = Get-MgOauth2PermissionGrant -All
foreach ($Grant in $Grants) {
foreach ($Scope in $HighRiskScopes) {
if ($Grant.Scope -match [regex]::Escape($Scope)) {
$SP = Get-MgServicePrincipal -ServicePrincipalId $Grant.ClientId -ErrorAction SilentlyContinue
Write-Host "[!] HIGH-RISK CONSENT: App=$($SP.DisplayName) ClientId=$($Grant.ClientId) Scope=$($Grant.Scope) ConsentType=$($Grant.ConsentType)" -ForegroundColor Red
}
}
}
# === STEP 4: List service principals created in the last 30 days (persistence check) ===
$Cutoff = (Get-Date).AddDays(-30)
Get-MgServicePrincipal -All | Where-Object { $_.AdditionalProperties.createdDateTime -and ([datetime]$_.AdditionalProperties.createdDateTime) -gt $Cutoff } |
Select-Object DisplayName, AppId, Id | Format-Table -AutoSize
# === STEP 5: Audit recent sign-in risk for the target user ===
Get-MgRiskDetection -Filter "userPrincipalName eq '$TargetUser'" -All -ErrorAction SilentlyContinue |
Select-Object RiskType, RiskLevel, RiskState, DetectedDateTime, IpAddress, Location |
Format-Table -AutoSize
Write-Host "[*] Containment steps complete. Review high-risk consents and disable unauthorized apps via: Remove-MgOauth2PermissionGrant -OAuth2PermissionGrantId <id>" -ForegroundColor Yellow
Remediation
Because this is an architectural threat rather than a patchable CVE, remediation is a combination of immediate containment hygiene and durable identity-hardening controls:
Immediate actions (this week):
- Revoke tokens, not just passwords, in every identity IR playbook. A stolen session cookie or refresh token survives a password reset. Your playbooks must include session revocation at the IdP and at each critical SaaS platform (many have their own token layers).
- Disable user consent for OAuth applications. Move to an admin-consent workflow in Entra ID (Enterprise Applications → Consent and permissions → disallow user consent). Audit existing grants using the script above and remove anything unapproved.
- Extend Conditional Access to customer-facing SaaS. If a SaaS platform federates to your IdP, it must inherit the same policies as your corporate apps: phishing-resistant MFA (FIDO2/passkeys), compliant-device requirements, and sign-in risk policies. 'Low-risk' customer portals holding corporate identities are not low-risk.
- Ingest SaaS and IdP audit logs into your SIEM. If you cannot see consent grants, token issuance, and sign-in anomalies for your SaaS estate, you are blind to this entire attack class. Prioritize Entra ID AuditLogs/SigninLogs and the audit APIs of your top five SaaS platforms.
Durable controls (this quarter):
- Deploy token protection where available. Entra ID token protection (Continuous Access Evaluation and token binding) ties session tokens to the device, breaking token-replay attacks outright.
- Shorten session lifetimes for high-privilege and integrated identities. Eight-hour (or shorter) sign-in frequency for admins and identities with SaaS-to-corporate integrations shrinks the window a stolen token is useful.
- Inventory SaaS integration trust paths. Map every OAuth grant, API key, webhook, and SSO trust between customer-facing SaaS and internal systems. Every one of those is a lateral movement path an attacker inherits with a single identity.
- Hunt proactively. Run the KQL queries above on a scheduled basis (weekly at minimum) — consent-grant anomalies and impossible-travel patterns are high-fidelity, low-noise detections in most environments.
The ASOS breach will not be the last of its kind in 2026. Identity is the perimeter now, and the organizations that treat SaaS sign-ins with the same rigor as firewall rules are the ones that will catch the next one at step one instead of step four.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.