🛡️ CVE-2026-54560 — cloudreve

🟠 CVSS 8.0 — High ✅ No Known Exploit NVD
8.0
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

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

Summary

Cloudreve's OAuth access tokens can bypass OAuth scope enforcement.

This does not appear to be the intended design. The documentation describes OAuth client permissions/scopes, the API

has an insufficient-scope error code, and the code comments say RequiredScopes(...) should verify scopes when a

token has scopes, while skipping checks only for non-scoped session-based authentication.

However, OAuth access tokens are issued without the OAuth client_id claim. Later, the JWT verifier only loads scopes

into the request context when claims.ClientID != "". Because the OAuth access token has no client_id, its scopes

are not loaded, and RequiredScopes(...) treats the request like a non-scoped first-party/session token and skips

scope checks.

As a result, a low-scope OAuth access token, for example one granted only openid, can call APIs requiring higher

scopes such as file, share, workflow, user setting, WebDAV account, and potentially admin scopes when the authorizing

user is an administrator.

Why this seems unintended

Cloudreve appears to have an explicit OAuth scope model:

1. The official docs describe OAuth client permissions/scopes and require the authorization request to include

requested scopes.

2. The API error code list includes an OAuth insufficient-scope error.

3. RequiredScopes(...) is used across sensitive API groups such as files, shares, workflows, user settings, WebDAV

devices, and admin APIs.

4. The middleware comment says scope checks are skipped only when hasScopes is false, for example session-based

authentication.

5. Default OAuth clients created during migration explicitly list scopes such as Files.Write, Workflow.Write, and

Shares.Write.

This suggests the intended design is:

  • First-party/session tokens may be non-scoped and skip OAuth scope checks.
  • OAuth access tokens should carry scope metadata and be checked against RequiredScopes(...).

The current implementation makes OAuth access tokens fall into the first category by mistake.

Affected code

In the OAuth authorization code exchange, Cloudreve passes both ClientID and Scopes into token issuance:

```go

token, err := tokenAuth.Issue(c, &auth.IssueTokenArgs{

User: user,

ClientID: s.ClientID,

Scopes: authCode.Scopes,

RefreshTTLOverride: refreshTTLOverride,

})

Location:

  • service/oauth/oauth.go

In Issue(...), the access token includes Scopes but does not include ClientID:

accessToken, err := jwt.NewWithClaims(jwt.SigningMethodHS256, Claims{

TokenType: TokenTypeAccess,

RegisteredClaims: jwt.RegisteredClaims{

Subject: uidEncoded,

NotBefore: jwt.NewNumericDate(issueDate),

ExpiresAt: jwt.NewNumericDate(accessTokenExpired),

},

Scopes: args.Scopes,

}).SignedString(t.secret)

By contrast, the refresh token does include both:

Scopes: args.Scopes,

ClientID: args.ClientID,

Location:

  • pkg/auth/jwt.go

During request authentication, scopes are only inserted into request context if ClientID is present:

if claims.ClientID != "" {

util.WithValue(c, ScopeContextKey{}, claims.Scopes)

}

Location:

  • pkg/auth/jwt.go

Then CheckScope(...) skips scope enforcement if no scopes are present in context:

hasScopes, tokenScopes := GetScopesFromContext(c)

if !hasScopes {

return nil

}

Location:

  • pkg/auth/jwt.go

RequiredScopes(...) relies on this check:

if err := auth.CheckScope(c, requiredScopes...); err != nil {

c.JSON(200, serializer.Err(c, err))

c.Abort()

return

}

Location:

  • middleware/auth.go

Sensitive route groups protected by RequiredScopes(...) include:

  • Files: Files.Read / Files.Write
  • Shares: Shares.Read / Shares.Write
  • Workflows: Workflow.Read / Workflow.Write
  • User settings and security info
  • WebDAV device/account management
  • Admin APIs: Admin.Read / Admin.Write

Location:

  • routers/router.go

Reproduction steps

1. Create or use an OAuth client with a low-privilege scope, for example only openid.

2. Complete the OAuth authorization code flow for a normal user with:

scope=openid

3. Exchange the authorization code via:

POST /api/v4/session/oauth/token

4. Decode the returned access token.

Expected token metadata should preserve enough OAuth client/scope context for later enforcement.

Actual behavior:

  • The access token contains the requested scopes.
  • The access token does not contain client_id.

5. Use the returned token as a bearer token:

Authorization: Bearer <access_token>

6. Call an API that requires a scope not granted to the OAuth app, for example an endpoint requiring Files.Read,

Files.Write, UserInfo.Write, or DavAccount.Write.

Expected result:

  • The request s

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. A user must be tricked into taking some action. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality high, integrity high, availability low.

Affected software

CVE-2026-54560 is recorded against 4 packages.

  • github.com/cloudreve/cloudreve
  • github.com/cloudreve/cloudreve/v3
  • github.com/cloudreve/cloudreve/v4
  • unknown

Timeline and source

Published on 22 July 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.

References

github.com (Advisory)
nvd.nist.gov (Advisory)
github.com (Web)
github.com (Web)

Details

Severity High
CVSS Score 8.0
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:L
CWE N/A
Public Exploit ✅ No
Source NVD
Published 2026-07-22
Updated 2026-08-12
Modified 2026-07-22
Fix URL N/A

Affected Packages

Software From version Fixed in
github.com/cloudreve/cloudreve
github.com/cloudreve/cloudreve/v3
github.com/cloudreve/cloudreve/v4
unknown

Similar Threats

Site Security Check

Is cloudreve part of your stack?

CVE-2026-54560 is rated CVSS 8.0 High. BotEraser scans your installation against known CVE records and tells you whether this vulnerability applies to the versions you actually run.

Scan My Site Free →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.