# Cloudreve: OAuth access tokens bypass scope enforcement due to missing client_id claim

Cloudreve OAuth access tokens omit the client_id claim, so the JWT verifier never loads scopes and RequiredScopes skips enforcement, letting low-scope tokens reach file, share, and admin APIs.

- Payout: Research
- Severity: high
- Program: Cloudreve
- Found by: EaEa0001
- Disclosed: 2026-07-20
- CVE: CVE-2026-54560
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-vgj4-345g-jcf8
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-vgj4-345g-jcf8
- Tags: area:web domain:api domain:web impact:privesc kind:research platform:ghsa sev:high tech:go tech:jwt tech:oauth technique:source-review vuln:access-control vuln:auth-bypass

**Target:** OAuth token issuance and JWT scope middleware in Cloudreve API
**Root cause:** Access tokens are issued with Scopes but without ClientID; the verifier only loads scopes into context when claims.ClientID != "", so CheckScope sees no scopes and returns nil, skipping enforcement.
**Steps:**
1. Create an OAuth client with only the `openid` scope.
2. Complete the authorization code flow with `scope=openid` for a normal user.
3. Exchange the code at `POST /api/v4/session/oauth/token`.
4. Decode the access token: it contains scopes but no `client_id`.
5. Call an endpoint requiring Files.Read/Files.Write/UserInfo.Write/DavAccount.Write with `Authorization: Bearer <access_token>`; the scope check is skipped and the request runs as the user.
**How found:** Reporter compared the documented OAuth scope model, the insufficient-scope error code, and the RequiredScopes middleware comment (skip only when hasScopes is false) against the code: access token issuance omits ClientID while refresh token includes it, and the verifier gates scope loading on ClientID presence.
**Exploitation:** A third-party OAuth app requests minimal scope (e.g. openid), gets user consent, and receives an access token. Because the token lacks client_id, scope enforcement is skipped, so the token acts as a broader bearer token for the same user, reaching files, shares, workflows, user settings, WebDAV, and admin APIs if the user is an administrator.
**Escalation:** If the authorizing user is an administrator, the same token reaches Admin.Read/Admin.Write endpoints since the admin identity check passes while the OAuth scope check is skipped.
**Insight:** When a middleware gates a security check on a claim's presence (here ClientID), audit every token-issuance path to confirm that claim is always set; a missing claim silently downgrades to the 'trusted first-party' branch.

