A malicious OAuth app gained access
Investigate consent abuse as an identity incident: permissions, users, tokens, app activity, and the path that convinced someone to approve it.
Scope
For Entra ID administrators responding to an unfamiliar enterprise application or suspicious delegated permission grant.
Start with the situation, not the slogan
An incident rarely arrives with a neat label. It arrives as a forwarded screenshot, a worried telephone call, or a monitoring alert written by a machine with no sense of occasion. In this case “A malicious OAuth app gained access” is the working heading, but the label is only a starting hypothesis. The useful work is to establish what happened, what can still happen, and which decision cannot safely wait.
Keep three clocks in view: the attacker’s opportunity, the business interruption, and the lifetime of the evidence. They do not run at the same speed. A hasty change may interrupt access but erase context; a perfect investigation conducted at geological pace may leave the organisation exposed. Good response is the slightly unglamorous art of making the next reversible decision with the best evidence currently available.
OAuth abuse can bypass a password reset because the application acts with granted permissions. The blast radius depends on consent type, permission scope, affected users, token lifetime, and the data the app accessed.
Composite scenario
How this usually reaches the desk
Imagine the report begins with this observation: “New consent events, service principals, credentials, or permission grants in Entra audit logs.” A second check returns another clue: “Application sign-ins or API activity from unexpected networks and at unusual volumes.” Neither fact alone tells the whole story. Together they justify a documented incident, a defined owner, and a deliberate containment decision. This is where a timeline beats a collection of heroic memories; memory is an excellent storyteller and a dreadful audit log.
This scenario combines common operational patterns; it is not presented as a report of one named incident.
What to look for
Begin with preserved, comparable evidence. One signal is rarely proof; use independent observations and a reliable timeline before declaring scope or intent.
New consent events, service principals, credentials, or permission grants in Entra audit logs.
Record the exact time, source, identity, system and time zone. Compare it with a known-good baseline and with what the user or service owner expected. A surprising event is a lead, not a conviction.
Application sign-ins or API activity from unexpected networks and at unusual volumes.
Look for the control-plane event that made the visible activity possible: a changed credential, permission, rule, route, token or trusted device. Persistence often looks administrative because, technically, it is.
User reports of a consent screen, unfamiliar app name, or access continuing after a password reset.
Correlate the report with independent telemetry before deciding scope. User testimony, identity logs, endpoint evidence and service audit records are strongest when they agree on sequence rather than merely on mood.
Working examples
Run it, read it, decide what changes
These examples use documentation addresses, test identities and bounded targets. Replace placeholders only inside systems you own or are explicitly authorised to operate. Read the expected result and next action before running the command; a successful command is evidence, not yet a conclusion.
Inventory OAuth grants for one user
- Prerequisites
- Graph PowerShell and `DelegatedPermissionGrant.ReadWrite.All` or an equivalent approved read role.
Connect-MgGraph -Scopes "DelegatedPermissionGrant.ReadWrite.All","Application.Read.All"
$user = Get-MgUser -UserId "alex@example.com"
Get-MgOauth2PermissionGrant -Filter "principalId eq '$($user.Id)'" |
Select-Object Id,ClientId,ResourceId,Scope,ConsentTypeThe output lists consent grant identifiers, client applications, resources and scopes.
Broad scopes such as mail or file access deserve an owner and business purpose. The client ID must be resolved to a service principal before judging the application.
Export the grants, resolve each client with `Get-MgServicePrincipal -ServicePrincipalId`, and remove only grants confirmed unauthorised through the supported Graph removal operation.
List service principals created in the review window
- Prerequisites
- Graph PowerShell, `Application.Read.All`, and a recorded UTC start time.
Connect-MgGraph -Scopes "Application.Read.All"
Get-MgServicePrincipal -All |
Where-Object {$_.CreatedDateTime -ge [datetime]"2026-08-18T08:00:00Z"} |
Select-Object DisplayName,AppId,Id,CreatedDateTime,AccountEnabledApplications created after the stated time are listed.
Creation time narrows the review but does not prove maliciousness. Pre-existing applications can receive new grants later.
Compare app owners, publisher verification, reply URLs, credentials and audit logs with the approved SaaS inventory.
Prove a consent grant is gone
- Prerequisites
- The recorded grant ID and permission to read grants.
$grantId = "00000000-0000-0000-0000-000000000000"
Get-MgOauth2PermissionGrant -OAuth2PermissionGrantId $grantId -ErrorAction SilentlyContinueNo object is returned after a successful removal; an existing object is printed if the grant remains.
Absence of one grant does not remove application credentials, other tenants, app-role assignments or stolen tokens.
Recheck service-principal assignments, revoke affected user sessions, and test that the application can no longer call the protected resource.
What to do
Read the whole sequence before starting. Several workstreams may run in parallel, but their evidence, authority and expected outcomes still need to be explicit. Every step below points back to a concrete example; use the example as implementation evidence, not as permission to operate outside the stated scope.
Operational judgement
Containment and recovery are different verbs. Containment limits the next harmful action; recovery returns a service to trustworthy operation. Between them sits eradication: removing the access path and persistence that would make the freshly restored service merely a cleaner target. For OAuth, Entra ID and Cloud, keep those decisions separate in the timeline even if a small team performs them minutes apart.
Communication is also a control. Tell affected people what is known, what remains uncertain, what they must do and when the next update will arrive. Avoid both melodrama and false reassurance. “We are investigating” is useful only when followed by an owner and a time. The goal is to reduce secondary harm without teaching a possible attacker exactly what the team has discovered.
Handover
Make the result useful to the next person
Maintain two views of the incident. The working timeline should contain detailed events, evidence locations, hypotheses and technical actions. The stakeholder update should contain confirmed impact, current containment, material uncertainty, decisions required and the next reporting time. Do not copy speculative indicators into executive statements. Equally, do not polish away uncertainty merely because it looks untidy. Both records should use absolute times with a declared time zone and should identify the source of each important fact.
At shift change, hand over the current scope, trusted administration path, preservation status, active controls, failed actions, business priorities and the next three decisions. Read back the most consequential assumptions. For this case, ensure the record begins with “Record the application ID, service principal, publisher information, permissions, consent type, owners, credentials, and affected users.” and does not finish until the team has addressed “Find the consent path—phishing link, compromised admin, misconfigured workflow, or supply-chain integration—and block recurrence with consent policies and review.” A concise, accurate handover prevents the incoming team from repeating disruptive work or mistaking a quiet telemetry gap for successful containment.
Validate before you close
Confirm that the app and credentials cannot authenticate, risky grants are removed, affected data stores were assessed, and future high-risk consent requires an approved workflow.
Capture the test, the expected result and the observed result. Where a person or business owner must accept restored service, name them in the record. A green dashboard can confirm that a component is answering; it cannot confirm that invoices, identities or restored data are trustworthy.
Finish with a compact closure note: the original trigger, confirmed scope, evidence retained, controls changed, tests passed, known gaps, residual risk, and the people responsible for the remaining work. Schedule a review while the timeline is still fresh enough to challenge. The purpose is not to find a person to blame; computers already perform blame with admirable efficiency. The purpose is to make the next response faster, safer and less dependent on one person remembering where the useful log was hidden.
Common mistakes
- Resetting systems before preserving volatile evidence and audit logs.
- Treating the first visible symptom as the complete scope of the incident.
- Restoring service without verifying that the attacker’s access path is closed.
These errors usually come from haste, unclear ownership or misplaced confidence. Build the safeguard into the runbook: a required evidence field, a second-person review, a rollback test or a specific exit criterion.
Questions people ask when the clock is running
Does one suspicious event prove compromise?
No. Treat “New consent events, service principals, credentials, or permission grants in Entra audit logs.” as a reason to investigate and preserve evidence. Confidence should rise when independent identity, service, endpoint or network records support the same sequence.
Should we reset everything immediately?
Reset or revoke what the evidence and risk justify, but preserve the state you will need to understand the incident. Broad, undocumented resets can interrupt the attacker, the business and the investigation in one impressively efficient stroke.
When can the incident be closed?
Confirm that the app and credentials cannot authenticate, risky grants are removed, affected data stores were assessed, and future high-risk consent requires an approved workflow. Closure also requires named owners for residual risk and follow-up work; “it seems quiet now” is an observation, not an exit criterion.
Safety boundary
Use these steps only on systems you own or are explicitly authorised to assess. Preserve evidence, follow your organisation’s legal and regulatory obligations, and prefer reversible actions when the situation is not yet understood.
Primary references
- View Activity Logs of Application PermissionsMicrosoft Learn
- Revoke User Access in an EmergencyMicrosoft Learn
- SP 800-61 Rev. 3: Incident Response Recommendations and ConsiderationsNIST
- Microsoft Graph PowerShell OverviewMicrosoft Learn
Editorial status: first edition. Review the linked vendor documentation for product- and version-specific changes before acting.