EresusSecurity
Back to Research
Identity Security

OAuth Consent Phishing Skips Both Your Password and Your MFA

Eresus Security Research TeamSecurity Researcher
November 5, 2026
16 min read
Threat AnalysisIdentity and Application Security

OAuth Consent Phishing Skips Both Your Password and Your MFA

There is a class of account takeover in which nothing is stolen. No credential is harvested, no session cookie is replayed, no MFA challenge is relayed. The victim opens the genuine sign-in page, types the genuine password, satisfies the genuine second factor, and clicks a button that looks exactly like every consent screen they have ever skipped. Thirty seconds later somebody else holds a refresh token, minted by your own identity provider, scoped to that mailbox and that drive, valid for months.

Core assessment: consent phishing and device-code phishing are not phishing tricks that happen to involve OAuth. They are a change of target. Every control bought in the last decade — MFA, passkeys, breached-password blocking, risk-based step-up, adversary-in-the-middle detection — defends the authentication plane. This attack runs on the authorization plane, where the user authenticated correctly and then volunteered access. Your second factor cannot refuse a grant your identity provider was asked to honour. The defence is consent gating, application allow-listing, token lifetime control and audit-log correlation, and most tenants have almost none of the four running.

Why the Attacker Changed Planes

Approach What the user is tricked into What the attacker receives Defeated by Survives MFA?
Fake login page Typing the password into a lookalike host Password, plus a one-time code if asked fast enough MFA, passkeys, breached-password blocking No
Adversary-in-the-middle relay Signing in to a proxied real page A live session harvested behind the relay Token binding, numbered verification, short session lifetimes Often
Consent-screen phishing Approving an application A delegated refresh token with declared scopes User-consent restrictions, admin consent, app allow-lists Yes
Device-code phishing Entering a code at the real verification page A delegated refresh token for a request the attacker started Disabling the flow, conditional access on authentication mode Yes

The economics moved, not the technique. Password phishing is a volume game with a hit rate that MFA keeps pushing toward zero. A consent grant is one-to-one: more effort per victim, far higher value per success, and durable in a way a stolen password is not. A password gets rotated inside an hour once anyone notices. A refresh token issued in the victim's name is a persistence mechanism that outlives the password change and, depending on configuration, the second-factor re-enrolment.

The Two Primary Flows

The sequence is short and every step of it is legitimate.

  1. Register an application. On mainstream cloud identity platforms this is self-service and near-free. The display name is checked by the platform's publisher-verification tier, which most registrants never buy because it costs money and requires documents. Marking the app multi-tenant means the victim's organisation does not see it in their own enterprise-application inventory until a user grants it a service principal.
  2. Request scopes. Not "read your basic profile". The catalogue that matters is mail read, mail send, mail read/write, files and sites read/write, directory read, chat or conversation read — plus offline_access, which is what converts one click into standing access.
  3. Send a link. The scheme, host and path all belong to the real identity provider. The client_id, scope and redirect_uri query parameters belong to the attacker. The page the user sees is rendered by the provider, not by anyone else. There is no spoof to find. Every heuristic a user was trained on — look at the domain, look for the padlock, don't type your password somewhere unfamiliar — passes.
  4. Pick a pretext that makes approval feel like opening a file. "The shared workbook is in this app", "your payslip is ready in the HR portal", "sign to receive the contract", "the meeting recording needs one click", "approve access to the project board". The pretext's only job is to make the Approve button the obvious next action.
  5. Collect the code, redeem the tokens. The redirect receives an authorization code and the attacker exchanges it, with their client secret for a confidential client or nothing at all for a public client.

A detail that matters for defenders: the redirect target does not have to be reachable infrastructure. An open redirect on a legitimate domain, a listener on the attacker's own machine, or a public client that simply shows the code in the browser all complete the flow. Blocking unknown redirect domains is not a control.

Device-code phishing

Device-code flow exists for devices without a keyboard: consoles, set-top boxes, smart TVs, IoT panels, some CLIs. A client asks the provider for a code, gets back a short human code plus a verification URL, and then polls until a human authorises it.

  1. The attacker starts the flow against any client that supports it. No victim interaction yet.
  2. The provider returns a user code and a verification URL. The code is not bound to the person who requested it. Anyone who authenticates at that URL and enters that code authorises the pending request.
  3. The attacker sends the pair to the victim: "helpdesk is enabling multi-factor, open this link and enter this code to finish enrolling", "confirm your sign-in to keep your access", "your manager shared a document, verify your device". Increasingly as a QR image so nobody has to type anything.
  4. The victim opens the genuine verification page, signs in with genuine credentials and a genuine second factor, and enters the code.
  5. The attacker's polling client receives the tokens.

The victim never shares a password. They spend a login. There is no artefact in that interaction that looks like an attack, which is precisely why the "don't share your code" awareness message fails: the user was not sharing a code, they were entering one into the real Microsoft or real Google page.

Where the two blend

  • Broker popups. Sign-in surfaced by an operating-system account helper rather than a browser tab, so the address bar the user was trained to inspect does not exist at all. The prompt reads "Continue in SomeApp" and the honest answer to whether that is safe requires capabilities a normal user does not have.
  • QR plus device code. A printed or emailed QR that opens the verification page with the code already filled in. It removes the copy-paste step, which was the only part of the pretext that felt strange.
  • Consent fatigue. A steady stream of benign prompts trains the click. On shared kiosks, training environments and second-hand devices this is deliberate.
  • Legacy surfaces. The flow stays enabled because it was enabled in 2018 for a device programme that ended, and the tenant has a habit of treating authentication modes as vendor defaults rather than as configuration.

What the Token Actually Buys

Granted capability What it unlocks How long it lasts Why it is worse than it sounds
Mail read Full mailbox, including other participants' threads and password-reset messages Until revoked Password resets for other accounts arrive in this mailbox
Mail send Send as the user, to internal recipients, with their reputation Until revoked The most effective internal phishing you can buy
Mail read/write Create inbox rules, delegates, forwarding Until revoked Covert exfiltration channel plus evidence suppression
Files/sites read-write Organisation content, not only the user's own Until revoked Lateral movement over API, invisible to network controls
Directory read Org chart, identities, licensing map, admin surface Until revoked Target selection for the rest of the campaign
Chat/conversation read Message history across teams and channels Until revoked Contains credentials, roadmap and client data by accident
offline_access Refresh token Months; survives password rotation on many configurations Persistence

Two honest qualifications. First, scopes are a ceiling, not a floor: an application granted tenant-wide file write does not need to walk the library to be damaging, it needs one file. Second, the delegated-versus-application permission distinction decides your blast radius. Delegated permissions act as the consenting user, so a single consent compromises one identity plus whatever that identity can reach through an API. Application permissions act as the application, are only grantable by a privileged administrator, and compromise the tenant. Triage that question first: one user said yes, or an administrator said yes.

Why Your Existing Detections Stay Silent

Control you already run Why it does not fire
MFA, including phishing-resistant authenticators The factor is satisfied, not bypassed. The user is who they say they are.
Breached-password blocking No password crosses an attacker-controlled endpoint.
Phishing-page and AiTM detection, browser isolation, URL reputation The host is the identity provider's own. Reputation, TLS and page-rendering checks all pass.
Sign-in risk: impossible travel, unfamiliar device, anonymised IP In device-code phishing the interactive sign-in can happen on the victim's own laptop from their usual address.
CASB or SaaS security posture app discovery Delegated API traffic presents as the user's own mail and drive activity; the client may be an unregistered public client rather than a vendor domain.
EDR No binary runs. The payload is a bearer token held in someone else's infrastructure.
DLP Exfiltration rides the provider's own API endpoints using scopes the provider approved.

The deeper reason is a data-model assumption. Nobody built a detection for "a user approved an application", because for fifteen years that event has meant procurement. It is low-volume, human-initiated and business-plausible. It is also the single highest-signal write in the entire identity audit stream.

The Detection That Works: Different Application, Different Identity

The structural tell is that the identity that authenticated and the application that received the token are different things, and the user's normal client never appears in the chain. Turning that into an alert takes three joins.

  1. Device-code correlation. Look for an authentication event whose target is the provider's own device-registration endpoint, followed by token issuance for a different client id. In phishing, the second event frequently comes from a different address block, a different user-agent, or no user-agent at all — a plain HTTP library polling a token endpoint is not a browser. A "success" against the device-authentication page with no matching interactive sign-in to the application that ends up with the token is a lead, not a false positive.
  2. Consent as an entity. Query application-consent audit records as a standing detection, not as a post-incident lookup. The fields worth alerting on: who consented, which client id, which scopes, whether the app's publisher is verified, and whether the service principal was created in your tenant or borrowed from another.
  3. Client-id cardinality. This is the cheapest high-yield hunt. Legitimate SaaS integrations are used by many users under one client id. An attacker's app is usually used by exactly one — and it appears once in the entire tenant history, then generates steady API traffic forever. A client id with a single user and a nonzero lifetime is anomalous in a way that is hard to accidentally trigger.

Then the follow-on signals, which are far higher confidence than the grant alone: an inbox rule, forwarding target or delegate created within minutes of a new consent; a new app registration by a non-engineering user; token refreshes from an address block that has never hosted an interactive sign-in for that user; and directory reads from a client that has no other business with that user.

State the limitation plainly: on some platforms the device-code authentication record does not name the application that will receive the token. You cannot always reconstruct the chain from the sign-in log alone. The sign-in event, the authorisation event and the token-issuance event have to be joined — and that join is exactly what most tenants have never built.

Containment, in the Order That Preserves the Answer

Sequencing matters here more than in most incidents, because two of the steps destroy each other's evidence.

  1. Export the consent and token-issuance records before you revoke. Revocation is a write into the same audit stream you need as evidence. Revoke first, collect later, and you lose the scope list that told you what was readable.
  2. Revoke the grant, not only the session. Session revocation invalidates issued access tokens. The refresh token bound to the offending client survives until the app consent or OAuth permissions are revoked — per user and per app. Do both, then block that client id tenant-wide.
  3. Keep the account unable to re-consent while you investigate. Re-enabling the mailbox an hour after blocking the app is how the same attacker gets back in with a new client id.
  4. Hunt before you flip the mailbox. Inbox rules, forward-and-keep, delegates, new app registrations, and — critically — the same client id granted by other users.
  5. Sweep the tenant for the client id. Consent phishing is rarely a single-victim event inside one organisation. The pretext normally went to a distribution list, a shared mailbox's watchers, or a supplier group.
  6. Reset the second factor if there is any indication the same user also met a relay page. Do not assume the two incidents are the same, and do not assume they are not. An attacker who can get a consent grant can usually also get a user onto an AiM page; they just prefer the one that needs no infrastructure.

Controls That Change the Outcome

Control What it blocks Cost or blind spot
Disable user consent, require an admin-consent workflow Any user volunteering a grant Support friction, and a request queue that users route around if app registration is still open
Restrict application registration to a security group The attacker's first step, when they register inside your tenant Nothing about externally registered multi-tenant apps
Deny consent to unverified-publisher applications Casual external apps Publisher verification proves a legal entity, not safe code. Treat it as a floor, not a review
Block device-code flow by conditional access, scoped to users who never need it Device-code phishing for privileged and administrative identities Breaks legitimate console, TV and CLI sign-ins; scoping by user and client is what makes it survivable
Short refresh-token lifetime, continuous access evaluation, revoke-on-risk Persistence Does not prevent the initial read
Allow-list the client ids permitted to obtain tokens for sensitive scopes Arbitrary clients reaching sensitive data Highest maintenance, and the most direct answer available
Monthly review of standing grants, by owner Consent drift and stale integrations Requires an owner; unowned reviews decay to zero
Block non-interactive creation of inbox rules, delegates and forwarding The usual follow-on Blunt; tune per tenant before it breaks assistants

One item deserves to be said out loud to whoever funds your awareness programme. Consent phishing is the case where "do not click suspicious links" fails structurally: the link is not suspicious and the page is not fake. If the training teaches the address bar, it teaches a signal this attack does not violate. Do not delegate to users a scope decision they cannot perform. "Read and send your email" is technically honest and practically meaningless — the legible version of a consent screen is a product problem, not a user-hygiene problem.

What to Test Before Someone Tests It

Three checks, each with a defensible evidence standard.

  • Can a non-administrator consent to high-impact scopes? Register a minimal public client in a second tenant, request mail read and offline_access, and send the URL to a test account. The finding is the outcome, not the configuration screenshot.
  • Is device-code flow reachable for privileged identities? Start the flow, then confirm whether your conditional access actually blocks the authorisation step, the token step, or neither. The two are different and a policy that appears to work often stops nothing.
  • Do the consent, sign-in and token records join in your SIEM, and does an alert fire? Inject the grant, measure detection latency, and record whether a human or a rule found it. A log you can query after the fact is not a detection.

Scope boundary matters: consent-testing inside your own tenant against your own accounts is authorised work. Probing the identity provider or a third-party application's registration process is not. Plan the engagement around your configuration and your telemetry, not around attacking upstream.

Frequently Asked Questions

It helps with the part it was designed for and nothing else. MFA raises the cost of reaching the consent or verification page as somebody else, so an attacker must still phish a real, authenticated human. It does not restrict what that authenticated human is allowed to approve. If your tenant relies on MFA as the answer to identity attacks, the correct follow-on control is a consent gate that no user can open, plus token-lifetime limits for anything that got through.

Can a scanner or a CSPM find the misconfiguration that enables it?

Partly, and the part it misses is the dangerous part. Posture tooling reports well: user consent enabled, app registration open to all employees, device-code flow allowed, unverified-publisher apps present, stale grants older than a year. What it cannot report is whether your detection chain actually works — whether an alert fires within a useful window when a new client id appears. That is an emulated-detection exercise, not a configuration read, and it is the difference between a hardening backlog and an answer.

What is the difference between delegated and application permissions when triaging?

Delegated permissions act as the consenting user, so the compromise is bounded by that identity's reach through the API. Application permissions act as the application itself, skip the user entirely, and can only be granted by someone with privileged rights. If a consent record shows an application permission over tenant mail, treat it as a tenant-level incident regardless of whose name is on the approval. If it shows delegated scopes, bound the investigation to that identity and the objects it can reach, then check whether the same client appears elsewhere.

Should I disable the device-code flow entirely?

If nobody in your estate legitimately signs in from a console, a set-top box, a smart TV or a keyboardless panel, disable it tenant-wide and stop thinking about it. Most organisations cannot, because a device programme from several years ago is still feeding a procurement habit. The sustainable version is a conditional access policy that denies the device-code authentication mode for privileged and administrative identities while leaving it available to the small group that needs it, and reviewing that group on a schedule.

Does moving to passkeys protect me from this?

No, and passkey adoption can make the picture worse if consent controls are not added at the same time. A passkey makes credential phishing and most relay attacks dramatically harder, which pushes attackers toward the path that still works: asking the passkey-authenticated user to authorise an application. Phishing-resistant authentication is a precondition for a trustworthy consent decision, not a substitute for restricting it.

Next Step

The measurable question is whether your telemetry joins a consent event to a token issuance and whether anyone is paged when it looks wrong. Eresus Security tests this as part of red team operations and incident response readiness, with identity attack paths covered end to end in our AI agent security and API security testing scopes. See Eresus Guard for the evidence standard we work to, and contact us to scope a consent and token-flow assessment.

AI Security Starter Training

Request a practical checklist for prompt injection, RAG data leakage, MCP risks, and model-file security before launch.

Prompt injection and guardrail bypass checks.
RAG data leakage and permission-boundary review.
MCP identity, transport, and command-risk controls.

No spam. Used only to send the resource and related security notes.

Related Research

Related Services

Scope Estimator

Get a rough engagement size before the scoping call.

What this depth covers
Full coverage of the OWASP-family test plan for the in-scope targets: broken access control, injection, authn and authz flaws, business-logic abuse, findings with reproduction steps.
What it does not cover
Multi-week adversary emulation, physical and phishing vectors, custom exploit development, source-code review.

Indicative effort

~5 tester-days

Estimate only, not a quote. It scales with the three factors above and assumes the targets are reachable and test accounts are provided in the test window.

Request exact scope