CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-49h3-cwhj-4737: Cloudreve: Path Traversal in WOPI PUT_RELATIVE Allows Arbitrary File Creation in Owner Account

mediumCVSS 4.3CVE-2026-55495
Summary Cloudreve's WOPI PUT_RELATIVE handler treats X-WOPI-SuggestedTarget as a path, not a filename. It splits the header on / and joins the segments onto the source file's directory with URI.JoinRaw, which feeds Go's url.JoinPath. url.JoinPath resolves ./.. segments, so a slash-bearing target such as a/../../evil.docx collapses to a location outside the source file's directory. The lower-level upload path then validates only the final, already-cleaned basename (evil.docx), which is harmless, and checks ownership against the *resolved ancestor* — which is still the same user's drive. A WOPI access token is bound to exactly one file (the route enforces fileId == session.FileID with a 403 otherwise). PUT_RELATIVE escapes that per-file scope: a token issued for one file can create (and, conditionally, overwrite) files elsewhere in the same account. Root cause (verified at 26b6b10) 1. Token is single-file scoped (the boundary being escaped) — middleware ViewerSessionValidation: fileId := hashid.FromContext(c) if fileId != session.FileID { // 403 — token is bound to ONE file c.Status(http.StatusForbidden); c.Abort(); return } Route: wopi := noAuth.Group("file/wopi", middleware.HashID(hashid.FileID), middleware.ViewerSessionValidation()); wopi.POST(":id", controllers.ModifyFile) → POST /api/v4/file/wopi/:id?access_token=<token>. **2. PUT_RELATIVE dispatch** — routers/controllers/wopi.go: case wopi.MethodPutRelative: // X-WOPI-Override: PUT_RELATIVE err = service.PutContent(c, true) 3. SuggestedTarget joined as a path — service/explorer/viewer.go: fileName, _ := wopi.UTF7Decode(c.GetHeader(wopi.SuggestedTargetHeader)) // X-WOPI-SuggestedTarget fileUriParsed, _ := fs.NewUriFromString(fileUri) if strings.HasPrefix(fileName, ".") { /* treat as extension */ } fileUri = fileUriParsed.DirUri().JoinRaw(fileName).String() // <-- path join, not basename ... subService := FileUpdateService{ Uri: fileUri } res, err := subService.PutContent(c, lockSession) 4. JoinRaw spli

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
medium — CVSS 4.3
Published
2026-07-24
Last updated
2026-07-24
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-49h3-cwhj-4737

Exploitation outlook

EPSS (FIRST.org) estimates each CVE’s probability of exploitation in the next 30 days — here is the CSIRTS.com read on those numbers.

Referenced CVEs

CVECSIRTS overviewExternal
CVE-2026-55495coverage & exploitation statusNVD · CVE.org

Same CVEs, other sources

How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.

More from GitHub Security Advisories