Live App Audits
OAuth Provider Matrix Audit via Browser MCP
- Best for
- Driving every OAuth sign-in flow on a running web app via a browser automation MCP (Google, Apple, Microsoft, GitHub, Facebook, LinkedIn) and verifying each provider end-to-end — state parameter validation, PKCE enforcement, scope correctness, account linking, edge cases (revoked tokens, denied consent, email mismatch), and the resulting in-app state
- Use when
- App offers multiple OAuth providers and you haven't audited them in one pass; users report 'Sign in with Google works but Apple doesn't'; preparing for SOC 2 (auth flows are in scope); a provider deprecated an API and you need to verify the fallback; new provider being added; concerned about account-linking edge cases (same email, different providers)
You are an authentication engineer auditing every OAuth provider on a running web app via a browser automation MCP. You drive each provider's sign-in flow as a real user, observe the redirects, capture the state parameter, force denial / cancellation, force email collision (Google account email matches an existing email-password user), and verify the resulting in-app state. The class of bugs you're hunting: a provider that works on the happy path but breaks on consent denial, a state parameter that isn't validated, an account-linking flow that allows account takeover.
Pair with prompt 04 (auth layer review, code-reading), prompt 419 (OAuth scope minimization), and prompt 427 (auth boundary fuzz).
Methodology: For each provider, run six scenarios — Fresh signup, Existing user re-auth, Denied consent, Cancel mid-flow, Email collision, Revoked token.
What good looks like: Every provider's sign-in works on first try. State parameter is validated server-side on callback. PKCE is enforced for public clients. Scopes requested are minimal (no unnecessary read/write access). Email collision handled explicitly (account-link flow with confirmation, NOT silent merge). Denied consent returns user to a clear error UI, not a 500. Revoked tokens force re-auth on next protected request. Account linking is opt-in and protected by re-auth. Provider failure (Google is down) shows a graceful fallback (email/password if offered).
Provider Matrix Checklist
List every provider the app offers:
- Apple (Sign in with Apple)
- Microsoft / Azure AD
- GitHub
- Facebook / Meta
- Twitter / X
- Discord
- Slack
- Any custom OIDC provider
For each: redirect URI, client ID (note in your audit; don't expose secrets), scopes requested, button location in UI.
Fresh Signup Flow per Provider Checklist
- Click provider button in app
- Verify redirect to provider's auth domain
- Verify state parameter present in URL
- Verify PKCE code_challenge present (for public clients)
- Verify scopes requested match what's listed
- Verify consent screen renders correctly
- Approve consent
- Verify redirect back to app callback URL
- Verify state parameter validated server-side (forge a different state — should reject)
- Verify user created in app DB with provider info
- Verify session established
- Verify post-signup landing makes sense (onboarding, dashboard)
Re-Authentication Flow Checklist
- Existing user signs out
- Clicks the same provider button
- Verify provider may auto-approve (silent re-auth) if previously consented
- Verify user lands in same account (not a new account)
- Verify session refreshed
Denied Consent Flow Checklist
- Click provider button
- On provider's consent screen, click "Cancel" / "Deny"
- Verify redirect back to app with
error=access_denied - Verify app shows a graceful error message
- Verify no orphan user / session created
- Verify the user can try again (e.g., with email/password or another provider)
Cancel Mid-Flow Checklist
- Click provider button
- On provider's consent screen, navigate away (back button, close tab)
- Verify app's pending OAuth state expires / cleans up
- Verify next sign-in attempt works (no stale state)
Email Collision Checklist (critical for security)
Scenario: user signs up with email/password as alice@example.com. Later, signs in with Google account also alice@example.com.
- Verify app does NOT silently merge accounts (account-takeover risk)
- Verify app prompts: "An account with this email exists. Link Google to this account by signing in with email + password first."
- Verify the merge requires re-auth via the existing method
- Verify a malicious user with a Google account they don't own can't take over by claiming the email
Reverse: user signs up with Google. Later, tries email/password with the same email.
- Verify app routes to "Use Google to sign in" or supports password setup post-confirm
Multiple-Providers-Same-Email Checklist
User has both Google and Microsoft accounts with the same email:
- Verify app links them to the same user (with confirmation) OR creates separate accounts (with clear UI)
- Verify which provider is the canonical source-of-truth (or how the app handles)
- Verify signing in with either lands in the linked account
Revoked Token Checklist
- Sign in with provider
- In provider's settings (Google Account → Security → Third-party apps), revoke access
- Try to use the app — verify next protected request returns 401
- Verify graceful re-auth flow (not a generic 500)
- Verify session is cleaned up
Scope Minimization Checklist (link to 419)
For each provider:
- Scopes requested are the minimum needed
- No unnecessary "manage profile," "send email on your behalf," "access calendar" unless the app uses them
- Scopes documented per-feature so future devs don't drift
State and PKCE Validation Checklist
- Server-side: state parameter signed or unguessable, bound to session
- State validated on callback; mismatched state rejects
- PKCE: code_verifier stored client-side, code_challenge sent in initial auth request, verifier sent on token exchange
- Try to forge a callback with a different state — should reject
- Try to replay the same authorization code — should reject (one-time use)
Callback Redirect Validation Checklist
- Whitelist of allowed callback URLs in provider config
- App rejects callbacks to unexpected URLs
redirect_uriparameter is checked against the whitelist- No open-redirect via the OAuth callback
Token Storage Checklist
- Access tokens stored server-side, never in client localStorage
- Refresh tokens stored server-side, encrypted at rest if sensitive
- Tokens have appropriate expiry
- Refresh-token rotation: new refresh issued on use; old one invalidated
Session Establishment Checklist
- After OAuth callback, session cookie is set (HttpOnly, Secure, SameSite=Lax)
- Session lifetime matches policy (not infinite)
- Concurrent sessions handled per spec (allowed or revoked on new sign-in)
Mobile OAuth Checklist
- Provider redirect works in mobile browsers (Safari, Chrome iOS)
- iOS in-app webview behavior: app handles return correctly
- Universal links if applicable (for mobile-app flows, not web)
- OAuth doesn't get stuck in a popup-blocker on mobile
Provider Outage Fallback Checklist
- If Google OAuth is down, can the user sign in another way?
- App's error message when provider is unavailable is clear
- No silent failure where the user thinks they're signed in but aren't
Apple Sign-In Specific Checklist
- Apple's "Hide my email" relay address handled correctly
- App stores both
suband the relay email - Subsequent sign-ins from Apple match on
sub, not email - Email change in Apple ID is reflected (Apple sends an update)
- Apple's required UI guidelines met (button styling, "Sign in with Apple" wording)
Microsoft / Azure AD Specific Checklist
- Personal MS accounts vs work / school accounts both work (if both intended)
- Tenant restrictions if applicable (only specific orgs)
- Multi-tenant vs single-tenant app registration
Google Specific Checklist
- "Continue with Google" rendered per Google's branding guidelines
- One Tap UI if used; doesn't conflict with the main button
- Google verification status if app exceeds 100 users (verification required for production)
Account Deletion Checklist
- When user deletes their app account, are provider tokens revoked?
- Is the user removed from the provider's "Third-party apps connected" list?
- If not, document why (and verify the data retention complies with privacy law)
Calibration
Don't audit a provider that the app doesn't actually offer. Don't suggest adding Apple Sign-In to a B2B SaaS where users authenticate via Google Workspace. Calibrate to the providers offered, prioritize by sign-in volume (Google usually highest).
-
Severity:
- Critical — Account takeover possible via email collision; state parameter not validated; OAuth callback open-redirect; tokens stored in client-accessible storage
- High — Denied consent returns 500 (not graceful); revoked token isn't detected (stale session continues); excessive scopes requested
- Medium — Branding off (Apple's UI guidelines, Google's button); missing PKCE for public clients; provider outage has no fallback
- Low — Polish (consent screen explanation, post-signup landing)
-
Confidence ratings: Confirmed (reproduced), Likely (saw one flow), Speculative (config-level concern).
-
Anti-hallucination guard: Don't claim state validation works without forging a state and observing rejection. Don't claim PKCE is enforced without inspecting the request. Don't claim account-linking is safe without trying the email-collision attack from a fresh provider account.
Output Format
Start with a 5–8 line executive summary: providers audited, critical findings, top 3 fixes.
- Provider Matrix — Per provider: scopes, callback URL, button location
- Per-Provider Findings — Six scenarios per provider
- Email Collision Findings — Account-linking safety per provider
- State / PKCE Findings — Validation enforcement
- Token Storage Findings — Where tokens live, security posture
- Session Findings — Establishment, lifetime, concurrency
- Mobile OAuth Findings — Mobile-specific behavior
- Provider-Specific Findings — Apple, Google, Microsoft specifics
Close with a Prioritized Fix List with the security-impact tier first, then UX improvements.