SaaS Token Theft and OAuth Consent Phishing: The 2025 Playbook
Attackers trick users into granting apps access. No password is stolen, but a long-lived token is. Stop it with scoped access, allow-lists, and immutable logging.
The problem
- Apps can request wide permissions like “read mail” or “manage files.”
- Users see a trusted SSO screen and click “Allow.” No password needed.
- Tokens last for hours to months, often refreshable, and bypass MFA.
- Attacker registers an app with a convincing name and icon.
- User gets a link to a real identity provider’s consent page.
- User clicks “Allow.” The attacker’s app receives an access/refresh token.
- Data is accessed via APIs without further prompts or MFA.
Design the defenses
- Tenant allow-list: Only approved apps can request consent.
- Least privilege scopes: Replace “read all” with specific folder/mailbox scopes.
- Admin consent workflow: Users request; security reviews; then approve.
- Short token lifetimes: Access tokens ≤1h, rotate refresh tokens.
- Conditional access: Block risky countries/devices; require compliant device.
- Immutable consent log: Append each approval/removal to a hash-chained ledger.
- Scope diffs: Alert when an app requests broader scopes than before.
- Unused-token sweeps: Revoke tokens not used in N days.
- Geo/device mismatch: Alert when tokens are used from new countries or unmanaged devices.
- Webhook traps: Honey-scopes to flag malicious apps quickly.
Simple policy users can understand
ALLOW consent if:
app in approved_list
AND scopes ⊆ minimal_required
AND device.posture = compliant
REQUIRE admin review if:
scopes include mailbox.read_all OR drive.read_all
DENY if:
app publisher not verified OR consent from unmanaged device
Quick setup checklist
| Task | Owner | Target |
|---|---|---|
| Disable end-user consent by default | IdP Admin | Today |
| Create an approved app catalog with scope templates | Sec/IT | This week |
| Set access tokens to ≤60 min; rotate refresh tokens | IdP Admin | This week |
| Write consents and revocations to immutable log | Sec Eng | Two weeks |
| Alert on broad scopes and publisher changes | SIEM/SOAR | Two weeks |
| Quarterly token hygiene: revoke stale tokens | Sec Ops | Recurring |
User guidance that actually helps
How do I spot a risky consent screen?
I already clicked “Allow.” What now?
Forensics and audit in one place
{
"event": "consent_granted",
"actor": "user:alice",
"app": "Calendar Helper",
"scopes": ["calendar.read"],
"device": "managed-laptop-42",
"ip": "203.0.113.10",
"timestamp": "2025-09-18T16:22:14Z",
"prev_hash": "b5f1...0a",
"sha3_256": "7a9c...55",
"sig": "dilithium3:base64..."
}
Takeaway: allow only known apps, keep scopes tight, shorten token lifetimes, and ledger every consent so you can prove who approved what and when.