{"id":"GHSA-qh53-mf6v-496j","revision":null,"records":[{"revision":"dfbf76adba0744bb8a0a908ddb4682e4","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-101056","aliases":[],"title":"Cloudreve before 4.16.1 Authentication Bypass via Cached Context Hint","description":"Cloudreve before 4.16.1 fails to revalidate share access when restoring cached navigator state from a context_hint UUID. Attackers who previously had valid share access can replay the cached hint to generate signed file URLs for up to 300 seconds after the share is deleted, expires, or reaches zero remaining downloads.","state":0,"publishedAt":"2026-09-27T17:02:38.06+00:00","modifiedAt":"2026-10-08T15:22:09.212+00:00","affected":[{"ecosystem":"Vendor product","name":"cloudreve","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"cloudreve\",\n                    \"product\": \"cloudreve\",\n                    \"defaultStatus\": \"unaffected\",\n                    \"versions\": [\n                        {\n                            \"version\": \"0\",\n                            \"status\": \"affected\",\n                            \"versionType\": \"semver\",\n                            \"lessThan\": \"4.16.1\"\n                        },\n                        {\n                            \"version\": \"4.16.1\",\n                            \"status\": \"unaffected\",\n                            \"versionType\": \"semver\"\n                        }\n                    ],\n                    \"packageURL\": \"pkg:golang/github.com/cloudreve/Cloudreve/v4\"\n                }"}],"metrics":[{"system":"CVSS 4.0","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N","score":6.9,"severity":"MEDIUM"},{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","score":5.3,"severity":"MEDIUM"}],"references":["https://github.com/cloudreve/cloudreve/security/advisories/GHSA-vx2m-jpxr-xv7w","https://www.vulncheck.com/advisories/cloudreve-before-4.16.1-authentication-bypass-via-cached-context-hint"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-101056","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-101056","identifiers":["CVE-2026-101056"]},"retained":false,"historicalAffected":[]},{"revision":"d8efb2f7ff63443fa83c4c7f152db540","observedAt":"2026-11-09T04:15:48.835+00:00","statement":{"source":"euvd","id":"EUVD-2026-87981","aliases":["CVE-2026-101056","GHSA-qh53-mf6v-496j"],"title":"Cloudreve before 4.16.1 fails to revalidate share access when restoring cached navigator state from a context_hint UUID. Attackers who previously had valid share access can replay the cached hint to generate signed file URLs for up to 300 s…","description":"Cloudreve before 4.16.1 fails to revalidate share access when restoring cached navigator state from a context_hint UUID. Attackers who previously had valid share access can replay the cached hint to generate signed file URLs for up to 300 seconds after the share is deleted, expires, or reaches zero remaining downloads.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 4.0","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N","score":6.9,"severity":null}],"references":["https://github.com/cloudreve/cloudreve/security/advisories/GHSA-vx2m-jpxr-xv7w","https://www.vulncheck.com/advisories/cloudreve-before-4.16.1-authentication-bypass-via-cached-context-hint"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-87981","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Sep 27, 2026, 5:02:38 PM","dateUpdated":"Oct 8, 2026, 3:22:09 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-87981","identifiers":["EUVD-2026-87981","CVE-2026-101056","GHSA-qh53-mf6v-496j"]},"retained":false,"historicalAffected":[]},{"revision":"e2069dd64df147ab9331e68a42e098f2","observedAt":"2026-10-25T04:17:26.915+00:00","statement":{"source":"nvd","id":"CVE-2026-101056","aliases":[],"title":"Cloudreve before 4.16.1 fails to revalidate share access when restoring cached navigator state from a context_hint UUID. Attackers who previously had valid share access can replay the cached hint to generate signed file URLs for up to 300 s…","description":"Cloudreve before 4.16.1 fails to revalidate share access when restoring cached navigator state from a context_hint UUID. Attackers who previously had valid share access can replay the cached hint to generate signed file URLs for up to 300 seconds after the share is deleted, expires, or reaches zero remaining downloads.","state":0,"publishedAt":"2026-09-27T18:16:31.667+00:00","modifiedAt":"2026-10-08T16:17:01.093+00:00","affected":[],"metrics":[{"system":"CVSS 4.0 · disclosure@vulncheck.com · Secondary","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","score":6.9,"severity":"MEDIUM"},{"system":"CVSS 3.1 · disclosure@vulncheck.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","score":5.3,"severity":"MEDIUM"}],"references":["https://github.com/cloudreve/cloudreve/security/advisories/GHSA-vx2m-jpxr-xv7w","https://www.vulncheck.com/advisories/cloudreve-before-4.16.1-authentication-bypass-via-cached-context-hint"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-101056","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-863"],"productCriteria":[],"sourceDates":{"published":"2026-09-27T18:16:31.667","lastModified":"2026-10-08T16:17:01.093"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-101056","identifiers":["CVE-2026-101056"]},"retained":false,"historicalAffected":[]},{"revision":"e210598ee11849b0bc9df249f1559a3a","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-vx2m-jpxr-xv7w","aliases":["CVE-2026-101056","GO-2026-6287"],"title":"Cloudreve has Broken Access Control - Revoked Share Access Still Allows Signed File URL Generation via Cached context_hint","description":"## Summary\n \nCloudreve's file-listing responses hand the client a `context_hint` (UUID) that is meant to speed up follow-up operations. When that hint is replayed on the `file/url` (and `file/thumb`) routes, DBFS caches a `shareNavigatorState` containing the already-loaded share root and share row.\n \nOn a later request carrying the same hint, `shareNavigator.RestoreState` repopulates `shareRoot`, and `shareNavigator.To` then **skips `Root`**. `Root` is the only place that re-checks `inventory.IsValidShare` (share expiry, remaining-download count, owner status, source-file validity) and the share password. As a result, a recipient who prewarms a context hint while access is valid can keep minting signed file URLs for already-known shared file paths for up to the context-hint TTL (`5 * 60` = 300 s) after the owner deletes the share or the share expires — plus the lifetime of any signed entity URL minted in that window.\n \nThis is a **revocation / expiry bypass**, not a way to discover unknown share contents: the attacker must already have had access to the share and must know the target file URI from a prior listing.\n\n## Root cause (verified at `26b6b10`)\n \n**1. List responses leak the hint and each file URI** — `service/explorer/response.go` populates `ListResponse.ContextHint` and `FileResponse.Path` (`f.Uri(false).String()`).\n \n**2. `file/url` and `file/thumb` accept the client-supplied hint** — `routers/router.go:631` and `:662`:\n \n```go\nfile.POST(\"url\",  middleware.ContextHint(), /* ... */ controllers.FileURL)\nfile.GET(\"thumb\", middleware.ContextHint(), /* ... */ controllers.Thumb)\n```\n \nThe `file` group's only auth gate is `middleware.RequiredScopes(types.ScopeFilesRead)` — there is **no** independent share-validation middleware on this route. All share validation lives inside DBFS.\n \n**3. The middleware trusts the header verbatim** — `middleware/file.go:41`:\n \n```go\nfunc ContextHint() gin.HandlerFunc {\n    return func(c *gin.Context) {\n        if c.GetHeader(dbfs.ContextHintHeader) != \"\" { // X-Cr-Context-Hint\n            util.WithValue(c, dbfs.ContextHintCtxKey{}, uuid.FromStringOrNil(c.GetHeader(dbfs.ContextHintHeader)))\n        }\n        c.Next()\n    }\n}\n```\n \n**4. DBFS restores cached navigator state on a hint hit** — `dbfs.go:745` (`ContextHintTTL = 5 * 60`, `dbfs.go:34`). On a miss it arms `PersistState`; the closure fires in `DBFS.Recycle()` at end of request.\n \n**5. Persisted share state carries the loaded `shareRoot` + `share` row** — `share_navigator.go:72`/`:85`. `RestoreState` reinstates `n.shareRoot`, `n.share`, `n.owner`, etc.\n \n**6. `Root` is the sole validity/password gate** — `share_navigator.go:114` → `inventory.IsValidShare(share)` (`inventory/share.go:227`: `IsShareExpired` checks `Expires.Before(now)` **and** `RemainDownloads <= 0`, plus owner-active and source-file checks) followed by the `share.Password` comparison.\n \n**7. `To` skips `Root` once `shareRoot` is set** — `share_navigator.go:181`:\n \n```go\nfunc (n *shareNavigator) To(ctx context.Context, path *fs.URI) (*File, error) {\n    if n.shareRoot == nil {            // restored state => NOT nil => Root() skipped\n        root, err := n.Root(ctx, path)\n        ...\n    }\n    ...\n}\n```\n \nThe single-file-share branch is **also** affected: it calls `latestSharedSingleFile`, which fetches `n.fileClient.GetByID(n.share.Edges.File.ID)` straight from the restored `share` with no revalidation (`share_navigator.go`).\n \n**8. A failed download hook does not block URL issuance** — `pkg/filemanager/manager/entity.go:250`:\n \n```go\nif err := m.fs.ExecuteNavigatorHooks(ctx, fs.HookTypeBeforeDownload, file); err != nil {\n    m.l.Warning(\"Failed to execute navigator hooks: %s\", err) // logged, NOT fatal\n}\n```\n \nThe share's `BeforeDownload` hook is `shareClient.Downloaded()` (`UpdateOneID(share.ID).AddDownloads(1).AddRemainDownloads(-1)`). Against a deleted share this update errors, but the error is only logged and the signed URL is still minted. The signed content endpoint `file/content/:id/...` is then guarded only by `middleware.SignRequired` — it does not re-check the share.\n\n## Steps to reproduce\n \n**Setup:** one share owner; one recipient (a second free account, or anonymous if the default anon group keeps share-download). Recipient knows the share URL (and password, if any).\n \n1. Recipient lists the valid share:\n   ```\n   GET /api/v4/file?uri=<share-uri> HTTP/1.1\n   Host: target\n   ```\n   Response includes `context_hint` and each file's `path`.\n2. While the share is still valid, recipient warms the cache for a known file:\n   ```\n   POST /api/v4/file/url HTTP/1.1\n   Host: target\n   X-Cr-Context-Hint: <context_hint>\n   Content-Type: application/json\n \n   {\"uri\":[\"<known-shared-file-uri>\"]}\n   ```\n   (cache MISS → `Root` runs → `PersistState` armed → `Recycle` writes `shareNavigatorState` to KV under `navigator_state_<hint>_share`.)\n3. Owner deletes the share, **or** it expires / hits zero remaining downloads.\n4. Within 300 s, recipient repeats the **same** request from step 2 (same `X-Cr-Context-Hint`, same URI).\n   (cache HIT → `RestoreState` sets `shareRoot` → `To` skips `Root` → `IsValidShare` never runs → signed entity URL returned.)\n5. The signed URL serves the file content; `file/content/:id/...` validates only the signature.\n**Expected:** step 4 returns `ErrShareNotFound` / `ErrShareLinkExpired`.\n**Actual:** step 4 returns a signed, downloadable URL.\n \n## Impact\n \nA former share recipient (including an anonymous one, under default permissions) can keep minting signed download URLs for already-known shared files for up to 300 s after the owner deletes the share or after time/download-limit expiry, plus the validity window of each signed URL minted in that period. It defeats owner revocation, time expiry, and the remaining-download limit, and bypasses password revalidation on cached state.\n \n## Remediation\n \n- On `RestoreState`, re-run `inventory.IsValidShare` and re-compare the current `share.Password` before trusting cached `shareRoot`; or bind the cached state to an authorization version that changes on any share edit/delete/download-limit change.\n- Do not store authorization-sensitive share state in context-hint cache; treat the hint as a pagination/perf token only.\n- Invalidate `navigator_state_*` entries when a share is edited or deleted.\n- Treat `HookTypeBeforeDownload` failures as blocking for share-backed downloads.\n- Add a regression test: list + prewarm hint, delete share, then `file/url` with the same hint must fail.","state":0,"publishedAt":"2026-08-24T22:01:03+00:00","modifiedAt":"2026-09-28T03:55:38.1833802+00:00","affected":[{"ecosystem":"Go","name":"github.com/cloudreve/Cloudreve/v4","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"last_affected","version":"4.0.0-20260606032813-26b6b1044b02"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/cloudreve/cloudreve/security/advisories/GHSA-vx2m-jpxr-xv7w","https://github.com/cloudreve/cloudreve"],"sourceUrl":"https://github.com/advisories/GHSA-vx2m-jpxr-xv7w","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-vx2m-jpxr-xv7w","identifiers":["GHSA-vx2m-jpxr-xv7w","CVE-2026-101056","GO-2026-6287"]},"retained":false,"historicalAffected":[]},{"revision":"d9a53cdb01c242af883376174654b3a3","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-6287","aliases":["CVE-2026-101056","GHSA-vx2m-jpxr-xv7w"],"title":"Cloudreve has Broken Access Control - Revoked Share Access Still Allows Signed File URL Generation via Cached context_hint in github.com/cloudreve/Cloudreve","description":"Cloudreve has Broken Access Control - Revoked Share Access Still Allows Signed File URL Generation via Cached context_hint in github.com/cloudreve/Cloudreve","state":0,"publishedAt":"2026-08-25T19:43:10+00:00","modifiedAt":"2026-09-28T03:55:38.1833802+00:00","affected":[{"ecosystem":"Go","name":"github.com/cloudreve/Cloudreve","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"}]}],"versions":[],"rawVersionEvidence":null},{"ecosystem":"Go","name":"github.com/cloudreve/Cloudreve/v3","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"}]}],"versions":[],"rawVersionEvidence":null},{"ecosystem":"Go","name":"github.com/cloudreve/Cloudreve/v4","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/cloudreve/cloudreve/security/advisories/GHSA-vx2m-jpxr-xv7w"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-6287","license":"OSV · upstream source license applies","key":"osv:GO-2026-6287","identifiers":["GO-2026-6287","CVE-2026-101056","GHSA-vx2m-jpxr-xv7w"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-10T18:23:45.7727801+00:00","complete":true,"records":1773,"lastAttemptAt":"2026-11-10T18:23:45.7727801+00:00","lastSuccessAt":"2026-11-10T18:23:45.9579119+00:00","error":null,"lastVerifiedAt":"2026-11-10T18:23:45.9579152+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-8859cf40d4337e24bd2f258cc7778fbad01bb24c79d057aaf34cf1dfc6f8917d-d220ab899e0e1c49e43094274f562c18c4a19b03898aec3feae1debdd31f6756","complete":true,"records":422212,"lastAttemptAt":"2026-11-10T18:21:27.6685178+00:00","lastSuccessAt":"2026-11-10T18:21:27.4920545+00:00","error":null,"lastVerifiedAt":"2026-11-10T18:21:27.6685178+00:00","snapshotPublishedAt":"2026-11-10T17:27:33+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-acbb624a79c244aa868394151a25f053","complete":true,"records":13704,"lastAttemptAt":"2026-11-10T18:24:12.0072206+00:00","lastSuccessAt":"2026-11-10T18:24:12.001+00:00","error":null,"lastVerifiedAt":"2026-11-10T18:24:12.001+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13758,"expectedIdentifiers":13758,"failedIdentifiers":0},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-10T18:23:45.7727801+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-10T18:23:45.7727801+00:00","lastSuccessAt":"2026-11-10T18:23:45.9591411+00:00","error":null,"lastVerifiedAt":"2026-11-10T18:23:45.9591459+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-4459456b8f8c43778c308d7de0a43211","complete":true,"records":13710,"lastAttemptAt":"2026-11-10T18:24:11.1447617+00:00","lastSuccessAt":"2026-11-10T18:24:11.141+00:00","error":null,"lastVerifiedAt":"2026-11-10T18:24:11.141+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13758,"expectedIdentifiers":13758,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-50a085e5b7a5d1546eabdb7e52fab85d658afa8554d3cf95a0891c49d83f2979","complete":true,"records":9935,"lastAttemptAt":"2026-11-10T18:23:45.7142755+00:00","lastSuccessAt":"2026-11-10T16:25:20.0114252+00:00","error":null,"lastVerifiedAt":"2026-11-10T18:23:45.7142755+00:00","snapshotPublishedAt":"2026-11-10T16:18:10+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-26503967ae4379db8f374089589d6e03fb15bd31f820c9e992aaf93840c2236c","complete":true,"records":1971,"lastAttemptAt":"2026-11-10T18:21:27.7170016+00:00","lastSuccessAt":"2026-11-09T21:02:20.472473+00:00","error":null,"lastVerifiedAt":"2026-11-10T18:21:27.7170016+00:00","snapshotPublishedAt":"2026-11-09T20:18:18+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-df497239f2f75af38e095cb498791dad4044a8a9a7f5f0ee6008bb732579ab9d","complete":true,"records":3081,"lastAttemptAt":"2026-11-10T18:23:45.7340645+00:00","lastSuccessAt":"2026-11-10T14:21:34.3717399+00:00","error":null,"lastVerifiedAt":"2026-11-10T18:23:45.7340645+00:00","snapshotPublishedAt":"2026-11-10T14:18:07+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-5bab1d7e68ac802e78d67f5b951f7bcace0c45048e98b39b73b18376172e4b36","complete":true,"records":231619,"lastAttemptAt":"2026-11-10T18:23:45.5819776+00:00","lastSuccessAt":"2026-11-10T18:23:44.1117746+00:00","error":null,"lastVerifiedAt":"2026-11-10T18:23:45.5819776+00:00","snapshotPublishedAt":"2026-11-10T17:33:21+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}