Multi-factor authentication has become the default answer to identity attacks — and for password-based credential theft, it remains essential. But as highlighted in the recent Dark Reading analysis on OAuth consent abuse, MFA is increasingly irrelevant to the attacks that actually succeed against cloud-first organizations in 2025 and into 2026. Threat actors have shifted from stealing passwords to stealing and abusing OAuth tokens and consent grants. When an attacker convinces a user to click 'Accept' on a malicious application consent prompt, MFA has already done its job — the user authenticated successfully. Everything that happens after that point lives outside MFA's scope.
This is not a theoretical concern. We've responded to multiple incidents in the past year where the initial access vector was a consent phishing campaign, often paired with adversary-in-the-middle (AiTM) phishing kits that capture session tokens outright. Once a malicious OAuth application holds delegated scopes like Mail.Read, offline_access, or Files.ReadWrite.All, the attacker maintains persistent access to mailboxes and files without ever needing the victim's password or MFA device again. Device code flow phishing (MITRE ATT&CK T1528 and T1550.004 territory) has compounded the problem, with campaigns abusing Microsoft's own device login pages to harvest tokens that satisfy Conditional Access policies.
If your identity security strategy begins and ends with 'we enforce MFA,' you have a gap. This post breaks down how OAuth consent abuse works from a defender's perspective, what to hunt for in Entra ID and Microsoft 365, and how to remediate and harden your tenant.
Technical Analysis
What Is Being Attacked
The target is the OAuth 2.0 authorization framework as implemented in Microsoft Entra ID (formerly Azure AD), Microsoft 365, and by extension Google Workspace. No software vulnerability is required — this is abuse of legitimate functionality. There is no CVE here; the attack surface is the consent model itself.
Affected platforms:
- Microsoft Entra ID tenants with default user consent settings (users allowed to consent to third-party apps)
- Microsoft 365 workloads exposed via Microsoft Graph delegated permissions (Exchange Online, SharePoint, OneDrive, Teams)
- Google Workspace environments with permissive app authorization policies
The Attack Chain
From an IR perspective, OAuth consent abuse typically unfolds in four stages:
-
Lure delivery. The victim receives a phishing email, Teams message, or malvertising link pointing to a legitimate Microsoft authorization endpoint (
login.microsoftonline.com/.../oauth2/v2.0/authorize) or the device code flow page (microsoft.com/devicelogin). Because the URL is genuinely Microsoft's, URL filtering and user suspicion both fail. -
Consent grant. The victim authenticates (MFA and all) and is presented with a consent screen for an attacker-registered application. These apps are typically named to mimic trusted software — 'DocuSign,' 'Adobe Document Cloud,' 'Microsoft Security Scanner,' or typosquats of internal app names. The requested scopes are the payload:
offline_access(refresh tokens),Mail.Read/Mail.ReadWrite,Mail.Send,Files.ReadWrite.All,Contacts.Read, andUser.Read. -
Token issuance and persistence. Entra ID issues access and refresh tokens to the attacker's application. Critically, revoking the user's password or resetting MFA does not invalidate refresh tokens or the consent grant itself. The attacker now has durable, MFA-independent access to the victim's mailbox and files via Microsoft Graph API calls from attacker-controlled infrastructure.
-
Post-compromise activity. We consistently observe mailbox reconnaissance, creation of inbox rules to hide attacker emails (auto-forwarding, moving responses to RSS or Archive folders), internal phishing sent from the compromised mailbox, and data exfiltration via Graph API bulk reads.
Exploitation Status
OAuth consent phishing is a confirmed, actively exploited technique in the wild — it has been used by nation-state actors (notably Midnight Blizzard/NOBELIUM in documented campaigns) and by commodity cybercriminals at scale throughout 2024–2026. AiTM phishing kits capable of session token theft are commercially available and widely deployed. This is not theoretical; it is one of the most common initial access vectors we see in cloud tenant compromises today.
Why MFA Doesn't Help
MFA validates the authentication event. OAuth consent abuse happens after authentication. The attacker never needs to authenticate as the victim again — they ride the issued tokens. Even phishing-resistant MFA (FIDO2, passkeys) protects the login ceremony, not the consent decision or the token lifecycle. The control gap is governance: what apps are allowed, what scopes they can request, who can approve them, and how quickly grants can be revoked.
Detection & Response
The telemetry you need lives in the Entra ID audit log (Consent to application, Add service principal, Add app role assignment to service principal), the unified audit log in Microsoft 365 (inbox rule creation, MailItemsAccessed), and Microsoft Graph sign-in data for token usage anomalies. Below are production-grade detections tuned to fire on genuinely suspicious behavior, not baseline noise.
SIGMA Rules
---
title: Suspicious OAuth Application Consent Grant with High-Risk Scopes
id: 8b3e7a41-2c5f-4d89-b1e6-9f4a2c7d3e5a
status: experimental
description: Detects user or admin consent grants to OAuth applications requesting high-risk Microsoft Graph delegated permissions commonly abused in consent phishing campaigns, such as offline_access combined with mail or file read/write scopes.
references:
- https://www.darkreading.com/vulnerabilities-threats/mfa-oauth-consent-abuse
- https://attack.mitre.org/techniques/T1528/
- https://attack.mitre.org/techniques/T1550/004/
author: Security Arsenal
date: 2026/01/15
tags:
- attack.credential_access
- attack.t1528
- attack.persistence
logsource:
product: azure
category: auditlogs
detection:
selection_operation:
OperationName: 'Consent to application'
selection_scopes:
ModifiedProperties|contains:
- 'offline_access'
- 'Mail.Read'
- 'Mail.ReadWrite'
- 'Mail.Send'
- 'Files.ReadWrite.All'
- 'Contacts.Read'
- 'MailboxSettings.ReadWrite'
condition: selection_operation and selection_scopes
falsepositives:
- Legitimate enterprise application onboarding (admin-consented, verified publisher)
- Approved third-party mail clients
level: high
---
title: New App Registration or Service Principal Credential Added by Non-Admin
id: 3f7d2b19-8e4a-4c61-a2f5-7b9e1d4c6a8f
status: experimental
description: Detects creation of new application registrations or addition of credentials (secrets/certificates) to existing service principals, a persistence technique used after initial access to maintain token-based access independent of user credentials.
references:
- https://www.darkreading.com/vulnerabilities-threats/mfa-oauth-consent-abuse
- https://attack.mitre.org/techniques/T1098/001/
author: Security Arsenal
date: 2026/01/15
tags:
- attack.persistence
- attack.t1098.001
- attack.privilege_escalation
logsource:
product: azure
category: auditlogs
detection:
selection:
OperationName:
- 'Add application'
- 'Add service principal credentials'
- 'Add service principal'
- 'Update application - Certificates and secrets management'
filter_known_admins:
InitiatedBy|contains:
- 'sync-service-account'
- 'terraform-service-principal'
condition: selection and not filter_known_admins
falsepositives:
- Legitimate developer and DevOps application registration activity
- Automated IaC pipelines (filter by known service principal names)
level: medium
---
title: Suspicious Inbox Rule Created to Hide or Forward Mail
id: 5c9a4f72-1d3b-4e58-9c2a-6f8b3a1d7e4c
status: experimental
description: Detects Exchange Online inbox rule creation with parameters commonly used after OAuth consent compromise to hide attacker correspondence or exfiltrate mail, such as forwarding to external addresses or moving messages to obscure folders like RSS Subscriptions.
references:
- https://www.darkreading.com/vulnerabilities-threats/mfa-oauth-consent-abuse
- https://attack.mitre.org/techniques/T1098/002/
- https://attack.mitre.org/techniques/T1114/003/
author: Security Arsenal
date: 2026/01/15
tags:
- attack.persistence
- attack.t1098.002
- attack.collection
- attack.t1114.003
logsource:
product: azure
service: exchange
detection:
selection_operation:
Operation:
- 'New-InboxRule'
- 'Set-InboxRule'
selection_suspicious:
Parameters|contains:
- 'ForwardTo'
- 'ForwardAsAttachmentTo'
- 'RedirectTo'
- 'RSS Subscriptions'
- 'DeleteMessage'
condition: selection_operation and selection_suspicious
falsepositives:
- Legitimate user-created forwarding rules to personal accounts (review for policy violation regardless)
- Helpdesk mailbox automation
level: high
KQL — Microsoft Sentinel / Defender
The following hunt query surfaces recent consent grants to unverified, rarely-seen applications requesting high-risk scopes. It correlates consent events with the publisher verification status and tenant-wide prevalence to suppress noise from legitimate enterprise app onboarding.
// Hunt: High-risk OAuth consent grants to unverified or low-prevalence applications
let HighRiskScopes = dynamic(["offline_access", "Mail.Read", "Mail.ReadWrite",
"Mail.Send", "Files.ReadWrite.All", "Contacts.Read", "MailboxSettings.ReadWrite",
"EWS.AccessAsUser.All", "full_access_as_user"]);
let ConsentEvents = AuditLogs
| where TimeGenerated > ago(14d)
| where OperationName =~ "Consent to application"
| extend InitiatedBy = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend TargetApp = tostring(TargetResources[0].displayName)
| extend TargetAppId = tostring(TargetResources[0].id)
| extend ModifiedProps = tostring(TargetResources[0].modifiedProperties)
| extend GrantedScopes = extract_all(@"Scope: ([^\"]+)", ModifiedProps)
| mv-apply Scope = GrantedScopes on (
where tostring(Scope) has_any (HighRiskScopes)
)
| project TimeGenerated, InitiatedBy, TargetApp, TargetAppId, OperationName, Result, CorrelationId;
// Flag apps with low tenant-wide consent prevalence (rare = suspicious)
let Prevalence = AuditLogs
| where TimeGenerated > ago(30d)
| where OperationName =~ "Consent to application"
| extend TargetApp = tostring(TargetResources[0].displayName)
| summarize AppConsentCount = count(), DistinctUsers = dcount(tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)) by TargetApp;
ConsentEvents
| join kind=leftouter Prevalence on TargetApp
| where AppConsentCount <= 3 or isempty(AppConsentCount)
| project TimeGenerated, InitiatedBy, TargetApp, TargetAppId, Result, AppConsentCount, CorrelationId
| sort by TimeGenerated desc;
// Companion hunt: inbox rules created within 24h of a consent grant (post-consent persistence)
let ConsentWindow = AuditLogs
| where TimeGenerated > ago(14d)
| where OperationName =~ "Consent to application"
| extend User = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| project ConsentTime = TimeGenerated, User, App = tostring(TargetResources[0].displayName);
OfficeActivity
| where TimeGenerated > ago(14d)
| where OfficeWorkload =~ "Exchange"
| where Operation in~ ("New-InboxRule", "Set-InboxRule")
| extend RuleParams = tostring(Parameters)
| where RuleParams has_any ("ForwardTo", "RedirectTo", "RSS Subscriptions", "DeleteMessage")
| join kind=inner ConsentWindow on $left.UserId == $right.User
| where TimeGenerated between (ConsentTime .. ConsentTime + 24h)
| project TimeGenerated, UserId, Operation, RuleParams, App, ConsentTime
| sort by TimeGenerated desc;
Velociraptor VQL
For endpoint forensics when investigating a suspected consent phishing or AiTM compromise, browser artifacts reveal whether the user visited the legitimate Microsoft consent or device-login endpoints at the time of the grant — useful for timeline reconstruction and for identifying which lure (authorize flow vs. device code flow) was used.
-- Hunt browser history for Microsoft OAuth authorize and device code flow visits
-- correlating with suspected consent phishing timeframes
SELECT Uid, Url, Title, from_unixtime(LastVisitTime / 1000000 - 11644473600) AS VisitTimeUTC,
"chrome" AS Browser
FROM Artifact.Windows.Forensics.History()
WHERE Url =~ 'login\.microsoftonline\.com/.*/oauth2/(v2\.0/)?authorize'
OR Url =~ 'microsoft\.com/devicelogin'
OR Url =~ 'login\.microsoftonline\.com/common/oauth2/deviceauth'
ORDER BY VisitTimeUTC DESC
Remediation Script — PowerShell
The following script audits your tenant for risky consent grants using Microsoft Graph PowerShell (MgGraph), identifies applications holding high-risk delegated scopes, and optionally revokes the offending grants. Run Connect-MgGraph with an account holding Application.Read.All, DelegatedPermissionGrant.ReadWrite.All, and Directory.Read.All.
# Requires: Connect-MgGraph -Scopes "Application.Read.All,DelegatedPermissionGrant.ReadWrite.All,Directory.Read.All"
$highRiskScopes = @('offline_access','Mail.Read','Mail.ReadWrite','Mail.Send',
'Files.ReadWrite.All','Contacts.Read','MailboxSettings.ReadWrite',
'EWS.AccessAsUser.All','full_access_as_user')
# Enumerate all OAuth2 permission grants (delegated consent) in the tenant
$grants = Get-MgOauth2PermissionGrant -All
$risky = foreach ($g in $grants) {
$scopes = $g.Scope -split ' '
$matched = $scopes | Where-Object { $highRiskScopes -contains $_ }
if ($matched) {
$sp = Get-MgServicePrincipal -ServicePrincipalId $g.ClientId -ErrorAction SilentlyContinue
[PSCustomObject]@{
GrantId = $g.Id
AppDisplayName = $sp.DisplayName
AppId = $sp.AppId
PublisherVerified = $sp.VerifiedPublisher.DisplayName
ConsentType = $g.ConsentType
RiskyScopes = ($matched -join ',')
}
}
}
$risky | Sort-Object AppDisplayName | Format-Table -AutoSize
$risky | Export-Csv -Path "RiskyConsentGrants_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation
# REVOCATION (uncomment after review): removes a specific risky grant by GrantId
# Remove-MgOauth2PermissionGrant -OAuth2PermissionGrantId '<GrantId>'
# HARDEN: disable user consent entirely - users must request admin approval instead
# (Requires Policy.ReadWrite.PermissionGrant)
# Update-MgPolicyAuthorizationPolicy -BodyParameter @{
# defaultUserRolePermissions = @{ permissionGrantPoliciesAssigned = @() }
# }
# AUDIT: list app registrations with client secrets added in the last 14 days (persistence check)
$cutoff = (Get-Date).AddDays(-14)
Get-MgApplication -All | ForEach-Object {
foreach ($cred in $_.PasswordCredentials) {
if ($cred.StartDateTime -gt $cutoff) {
[PSCustomObject]@{ App = $_.DisplayName; AppId = $_.AppId
SecretAdded = $cred.StartDateTime; KeyId = $cred.KeyId }
}
}
} | Format-Table -AutoSize
Remediation
There is no patch for consent abuse — remediation is governance. Prioritize the following, in order:
Immediate (this week):
- Audit existing consent grants. Run the PowerShell audit above (or review Enterprise applications → Permissions in the Entra admin center). Revoke any grant to unverified publishers holding mail, file, or offline_access scopes. Deleting the enterprise application (
Remove-MgServicePrincipal) also invalidates its tokens. - Disable user consent. Set User consent settings to Do not allow user consent and enable the admin consent workflow so requests route to reviewers with context. This is the single highest-impact change; it converts an invisible user decision into a governed approval.
- Revoke active sessions for affected users. After removing a malicious grant, run
Revoke-MgUserSignInSession(orRevoke-AzureADUserAllRefreshToken) for every user who consented, then force password reset and MFA re-registration review. Remember: password reset alone does not kill refresh tokens. - Hunt for post-consent persistence. Search for inbox rules, mailbox forwarding (
ForwardingSmtpAddress), and MailItemsAccessed events in the 30 days following each grant.
Short term (30 days):
- Enable Microsoft Graph activity logs and route Entra audit logs, sign-in logs, and unified audit logs to your SIEM with the detections above deployed.
- Restrict app registration. Disable Users can register applications unless there is a documented business need, and require publisher verification for anything that remains.
- Deploy Conditional Access token protection (preview/GA features in Entra ID P2) to bind tokens to devices, reducing the value of stolen refresh tokens. Evaluate Continuous Access Evaluation (CAE) enforcement for Exchange and SharePoint.
- Alert on device code flow usage (
authenticationProtocol/ unusualmicrosoft.com/devicelogincompletions) if your organization does not legitimately use it — most don't.
Ongoing:
- Train users on consent screens specifically. Standard phishing training teaches users to check URLs — useless here because the URL is genuinely Microsoft. Teach them to scrutinize the app name and requested permissions, and to report unexpected consent prompts the same way they report phish.
- Review consent grants quarterly and expire admin-consented app secrets on a defined lifecycle.
Reference: Microsoft documentation on configuring user consent settings, admin consent workflow, and detecting and remediating illicit consent grants.
MFA remains a mandatory control — but it is a gate at the front door, not a guard for the tokens issued inside. Consent governance, least-privilege scopes, continuous monitoring, and rapid revocation are what close this gap.
Related Resources
Security Arsenal Managed SOC Services AlertMonitor Platform Book a SOC Assessment soc-mdr Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.