Illicit Consent Grant: Investigating Rogue OAuth Apps
How to spot an illicit OAuth consent grant in the Unified Audit Log and Entra audit logs, which scopes matter, and how to remove the app's access.
TL;DR. In an illicit consent grant, a user clicks Accept on a consent prompt and an attacker's app gets delegated access to their mailbox or files, with its own refresh tokens. Look for Consent to application (plus Add delegated permission grant, Add app role assignment to service principal, Add service principal) in the UAL or Entra audit log, read ConsentAction.Permissions for scopes such as Mail.ReadWrite, Mail.Send, Files.ReadWrite.All, offline_access, and check ConsentContext.IsAdminConsent. Password resets and MFA do not remove the access; revoking the grant does.
Consent phishing is attractive because it skips the password entirely. Microsoft's own guidance puts it plainly: normal remediation steps such as resetting passwords or requiring MFA are not effective against it, because the app is external to the organisation (Microsoft Learn). In BEC cases I also see it as a second step: the attacker, already in the mailbox through a stolen session, consents to a "mail sync" app to keep access after the session is revoked. MITRE maps it to Steal Application Access Token (T1528).
What the audit trail looks like
A single consent often produces several records within a second or two:
Operation (Entra audit / UAL AzureActiveDirectory) | Meaning |
|---|---|
Add service principal | The app appears in the tenant (first consent by anyone) |
Add delegated permission grant | Delegated scopes granted (an oauth2PermissionGrant) |
Add app role assignment to service principal | Application permissions granted (admin consent) |
Consent to application | The consent itself, with context |
In the UAL, names often end with a dot (Consent to application.). The details are in ModifiedProperties:
| Property | What to read |
|---|---|
ConsentContext.IsAdminConsent | True: an admin consented for the tenant; Microsoft calls this out as a possible broad grant |
ConsentContext.OnBehalfOfAll | True: consent for all users |
ConsentAction.Permissions | The scopes, e.g. Scope: Mail.ReadWrite Mail.Send offline_access User.Read, and ConsentType: Principal (one user) or AllPrincipals |
TargetId.ServicePrincipalNames | The app ID |
| Target display name | The app's name, often generic ("Mail Sync", "PDF Viewer", "Secure Docs") |
Also note the actor, the IP and time. A consent from the same IP or session as a replayed sign-in is attacker activity, even if the "user" clicked.
Scopes that should worry you
| Scope | Why |
|---|---|
Mail.Read, Mail.ReadWrite | Read (and alter) the mailbox through Graph |
Mail.Send | Send as the user: the BEC payload |
MailboxSettings.ReadWrite | Create inbox rules and forwarding through the API |
Files.Read.All, Files.ReadWrite.All, Sites.Read.All | Everything the user can reach in OneDrive and SharePoint |
offline_access | A refresh token: long-lived access without the user |
full_access_as_user, EWS.AccessAsUser.All, IMAP.AccessAsUser.All | Legacy full mailbox access |
Directory.ReadWrite.All, RoleManagement.ReadWrite.Directory, AppRoleAssignment.ReadWrite.All | Tenant takeover if granted by an admin |
User.Read alone (sign-in and profile) is normal for "Sign in with Microsoft" apps. offline_access plus any mail scope for an app nobody recognises is not.
Confirming and scoping
Microsoft's detection and remediation guide suggests inventorying grants per user (Entra admin center → Users → the user → Applications), with PowerShell across the tenant, or by asking users to review their apps at myapps.microsoft.com. When reviewing, it points to AllPrincipals consents for non-Microsoft apps, Read/Write/All permissions, high-value users, and suspicious app names.
Then scope what the app did. Its activity is logged under the app's identity: MailItemsAccessed records with the app's AppId / ClientAppId, Graph activity if you have Microsoft Graph activity logs, and sign-ins of the service principal. The CISA/FBI advisory on the 2023 Exchange Online intrusion described how unexpected ClientAppID and AppID values in MailItemsAccessed records exposed the activity (AA23-193A). See MailItemsAccessed: what it proves.
Related persistence on the app side
Attackers with admin rights go further than consent:
Add service principal credentials/Update application – Certificates and secrets management: a secret or certificate added to an existing app, which lets the attacker authenticate as the app (T1098.001).Add application: a new app registration in the tenant.Add member to rolewith an application as member: a privileged role for the app.
These survive user password resets and deserve the same review.
How M365 Forensics flags it
The in-browser analyser has four related findings:
| Finding | Severity | Trigger |
|---|---|---|
| Consent granted to an app with mailbox or file access | High | Consent, delegated grant or app role assignment whose properties include a scope from its risky list (Mail.ReadWrite, Mail.Send, Files.ReadWrite.All, offline_access, full_access_as_user…) |
| Consent granted to an application | Low | Any other consent: check it is expected |
| Credentials added to an application | High | Secret or certificate added to an app or service principal |
| New application or service principal | Low | App registered or service principal added |
If the consent came from a suspicious sign-in's IP or session, the correlation finding adds a critical "action performed from the attacker's session". The remediation checklist then lists Remove the consented application and Restrict user consent.
Remediation
- Revoke the grant: in Entra, the user → Applications → the app → Remove; or
Remove-MgOauth2PermissionGrantfor delegated grants andRemove-MgServicePrincipalAppRoleAssignmentfor app role assignments (both referenced in Microsoft's guide). - Delete or disable the service principal if the app is not legitimate, so nobody else can use it.
- Revoke the user's sessions as well: the attacker who consented probably had a session too.
- Restrict user consent: allow users to consent only to verified publishers and low-risk permissions, and enable the admin consent workflow (configure user consent).
- Review app credentials, owners and roles added in the same period.
Frequently asked questions
What is an illicit consent grant?
An attack where a user, or an admin, is tricked into granting an attacker-controlled application permission to their data, such as reading and sending mail. The app then accesses the data with its own tokens, without the user's password.
Which audit events show a consent grant?
Consent to application in the Unified Audit Log and Entra audit log, usually with Add delegated permission grant or Add app role assignment to service principal, and often Add service principal when the app is new to the tenant.
Does a password reset remove the app's access?
No. The consent and the app's refresh tokens are independent of the user's password. Remove the permission grant, and delete the service principal if the app is not legitimate.
Further reading
- Microsoft Learn: Detect and remediate illicit consent grants
- Microsoft 365 BEC investigation guide
- OAuth apps are also a GitHub persistence path: githubforensics.com.