CVE-2026-79913
Cloudreve: SSRF guard bypass: checkIP does not decode IPv6-transition wrappers (NAT64, IPv4-compatible, 6to4) reaching internal and cloud-metadata addresses
Cloudreve is a self-hosted file management and sharing system. Prior to 4.18.0, the ValidateExternalURL server-side request forgery guard in pkg/request/ssrf.go passes resolved addresses to checkIP without decoding NAT64, IPv4-compatible, and 6to4 IPv4-in-IPv6 transition forms. An authenticated user with remote-download access can provide SrcUri through RemoteDownloadTask.createDownloadTask so a wrapper embedding a loopback, private, link-local, or cloud metadata IPv4 address is classified as public and fetched, exposing internal service responses and cloud instance credentials. IPv4-mapped IPv6 addresses remain blocked because Go converts that form with net.IP.To4. This issue is fixed in version 4.18.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
6.5
Cloudreve: SSRF guard bypass: checkIP does not decode IPv6-transition wrappers (NAT64, IPv4-compatible, 6to4) reaching internal and cloud-metadata addresses
Cloudreve is a self-hosted file management and sharing system. Prior to 4.18.0, the ValidateExternalURL server-side request forgery guard in pkg/request/ssrf.go passes resolved addresses to checkIP without decoding NAT64, IPv4-compatible, and 6to4 IPv4-in-IPv6 transition forms. An authenticated user with remote-download access can provide SrcUri through RemoteDownloadTask.createDownloadTask so a wrapper embedding a loopback, private, link-local, or cloud metadata IPv4 address is classified as public and fetched, exposing internal service responses and cloud instance credentials. IPv4-mapped IPv6 addresses remain blocked because Go converts that form with net.IP.To4. This issue is fixed in version 4.18.0.
- Record
CVE-2026-79913- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-918, CWE-697
- Updated
- 2026-11-02
EUVDEUVD-2026-84527
6.5
Cloudreve is a self-hosted file management and sharing system. Prior to 4.18.0, the ValidateExternalURL server-side request forgery guard in pkg/request/ssrf.go passes resolved addresses to checkIP without decoding NAT64, IPv4-compatible, and 6to4 IPv4-in-IPv6 transition forms. An authenticated user with remote-download access can provide SrcUri through RemoteDownloadTask.createDownloadTask so a wrapper embedding a loopback, private, link-local, or cloud metadata IPv4 address is classified as public and fetched, exposing internal service responses and cloud instance credentials. IPv4-mapped IPv6 addresses remain blocked because Go converts that form with net.IP.To4. This issue is fixed in version 4.18.0.
- Record
EUVD-2026-84527- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-jvh5-97xg-v99f
6.5
Cloudreve: SSRF guard bypass: checkIP does not decode IPv6-transition wrappers (NAT64, IPv4-compatible, 6to4) reaching internal and cloud-metadata addresses
Summary
Cloudreve's server-side request forgery guard ValidateExternalURL (pkg/request/ssrf.go) resolves a user-supplied URL host and rejects it when any resolved IP is a loopback, private, link-local, multicast, unspecified, CGNAT, or the cloud-metadata address. The classification is performed by checkIP, which uses Go's net.IP builtins (IsLoopback, IsPrivate, IsLinkLocalUnicast, ...) directly on the resolved address. These builtins inspect only the outer IPv6 address and do not decode IPv4-in-IPv6 transition wrappers. An attacker who controls a hostname's AAAA record (or, on a DNS64/NAT64 network, any hostname) can point the remote-download URL at a NAT64 well-known-prefix address (64:ff9b::a.b.c.d, RFC 6052), an IPv4-compatible address (::a.b.c.d, RFC 4291), or a 6to4 address (2002:AABB:CCDD::, RFC 3056) that wraps an internal IPv4. Go classifies these wrappers as ordinary global IPv6 addresses, so checkIP accepts them; the network then delivers the request to the embedded internal IPv4 (loopback, RFC 1918, or the cloud instance metadata service 169.254.169.254). This bypasses the SSRF guard that was added to block direct access to internal services.
Affected component and versions
- Component:
pkg/request/ssrf.go(ValidateExternalURL/checkIP), reached from the remote-download workflowpkg/filemanager/workflows/remote_download.go(RemoteDownloadTask.createDownloadTask, which passes the user-suppliedSrcUritoValidateExternalURL). - Affected: Cloudreve
<= 4.17.0(latest release at time of report) and currentmain. - Reachable by an authenticated remote-download user; administrative privileges are not required.
Vulnerable form vs correctly-guarded sibling
checkIP DOES block IPv4-mapped IPv6 (::ffff:a.b.c.d), because Go's net.IP.To4() returns the embedded IPv4 for that form and the standard checks then fire. It does NOT block the other IPv4-in-IPv6 transition forms, because for those To4() returns nil and every net.IP classifier reports the wrapper as a normal global IPv6 address:
- NAT64 well-known prefix
64:ff9b::/96(RFC 6052):64:ff9b::a9fe:a9feembeds169.254.169.254. - IPv4-compatible
::a.b.c.d(RFC 4291):::a9fe:a9feembeds169.254.169.254. - 6to4
2002::/16(RFC 3056):2002:a9fe:a9fe::embeds169.254.169.254.
The fix is to canonicalize the resolved address to its embedded IPv4 before classification, symmetric to how IPv4-mapped addresses are already handled by To4(). The same gap was fixed correctly in a sibling project: makeplane/plane apps/api/plane/utils/ip_address.py _embedded_ipv4() decodes IPv4-mapped, 6to4, Teredo and NAT64 before classifying; Cloudreve's guard is the unpatched twin of that pattern.
Severity
An authenticated low-privilege user can force the server to fetch attacker-chosen internal URLs and read the responses, including cloud instance-metadata credentials, producing a scope change from the download subsystem to the internal network and the host's cloud identity.
Proof of concept
The guard file pkg/request/ssrf.go imports only the Go standard library, so ValidateExternalURL was compiled and called verbatim from tag 4.17.0. The remote-download workflow calls it as ValidateExternalURL(ctx, SrcUri, opt) with default options.
Direction 1 (shipped guard accepts the internal-embedding wrappers):
=== Cloudreve v4.17.0 ValidateExternalURL (shipped, unmodified) ===
[ACCEPTED] NAT64 -> 169.254.169.254 (cloud metadata) http://[64:ff9b::a9fe:a9fe]/latest/meta-data/
[ACCEPTED] NAT64 -> 127.0.0.1 (loopback) http://[64:ff9b::7f00:1]/
[ACCEPTED] NAT64 -> 10.0.0.1 (RFC1918) http://[64:ff9b::a00:1]/
[ACCEPTED] IPv4-compatible -> 169.254.169.254 http://[::a9fe:a9fe]/latest/meta-data/
[ACCEPTED] IPv4-compatible -> 127.0.0.1 http://[::7f00:1]/
[ACCEPTED] 6to4 -> encodes 169.254.169.254 …
- Record
GHSA-jvh5-97xg-v99f- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-697, CWE-918
- Updated
- 2026-11-02
NVD
6.5
Cloudreve is a self-hosted file management and sharing system. Prior to 4.18.0, the ValidateExternalURL server-side request forgery guard in pkg/request/ssrf.go passes resolved addresses to checkIP without decoding NAT64, IPv4-compatible, and 6to4 IPv4-in-IPv6 transition forms. An authenticated user with remote-download access can provide SrcUri through RemoteDownloadTask.createDownloadTask so a wrapper embedding a loopback, private, link-local, or cloud metadata IPv4 address is classified as public and fetched, exposing internal service responses and cloud instance credentials. IPv4-mapped IPv6 addresses remain blocked because Go converts that form with net.IP.To4. This issue is fixed in version 4.18.0.
- Record
CVE-2026-79913- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-697, CWE-918
- Updated
- 2026-11-02
OSV
6.5
Cloudreve: SSRF guard bypass: checkIP does not decode IPv6-transition wrappers (NAT64, IPv4-compatible, 6to4) reaching internal and cloud-metadata addresses
Cloudreve is a self-hosted file management and sharing system. Prior to 4.18.0, the ValidateExternalURL server-side request forgery guard in pkg/request/ssrf.go passes resolved addresses to checkIP without decoding NAT64, IPv4-compatible, and 6to4 IPv4-in-IPv6 transition forms. An authenticated user with remote-download access can provide SrcUri through RemoteDownloadTask.createDownloadTask so a wrapper embedding a loopback, private, link-local, or cloud metadata IPv4 address is classified as public and fetched, exposing internal service responses and cloud instance credentials. IPv4-mapped IPv6 addresses remain blocked because Go converts that form with net.IP.To4. This issue is fixed in version 4.18.0.
- Record
CVE-2026-79913- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-697, CWE-918
- Updated
- 2026-11-02
OSVGHSA-jvh5-97xg-v99f
6.5
Cloudreve: SSRF guard bypass: checkIP does not decode IPv6-transition wrappers (NAT64, IPv4-compatible, 6to4) reaching internal and cloud-metadata addresses
Summary
Cloudreve's server-side request forgery guard ValidateExternalURL (pkg/request/ssrf.go) resolves a user-supplied URL host and rejects it when any resolved IP is a loopback, private, link-local, multicast, unspecified, CGNAT, or the cloud-metadata address. The classification is performed by checkIP, which uses Go's net.IP builtins (IsLoopback, IsPrivate, IsLinkLocalUnicast, ...) directly on the resolved address. These builtins inspect only the outer IPv6 address and do not decode IPv4-in-IPv6 transition wrappers. An attacker who controls a hostname's AAAA record (or, on a DNS64/NAT64 network, any hostname) can point the remote-download URL at a NAT64 well-known-prefix address (64:ff9b::a.b.c.d, RFC 6052), an IPv4-compatible address (::a.b.c.d, RFC 4291), or a 6to4 address (2002:AABB:CCDD::, RFC 3056) that wraps an internal IPv4. Go classifies these wrappers as ordinary global IPv6 addresses, so checkIP accepts them; the network then delivers the request to the embedded internal IPv4 (loopback, RFC 1918, or the cloud instance metadata service 169.254.169.254). This bypasses the SSRF guard that was added to block direct access to internal services.
Affected component and versions
- Component:
pkg/request/ssrf.go(ValidateExternalURL/checkIP), reached from the remote-download workflowpkg/filemanager/workflows/remote_download.go(RemoteDownloadTask.createDownloadTask, which passes the user-suppliedSrcUritoValidateExternalURL). - Affected: Cloudreve
<= 4.17.0(latest release at time of report) and currentmain. - Reachable by an authenticated remote-download user; administrative privileges are not required.
Vulnerable form vs correctly-guarded sibling
checkIP DOES block IPv4-mapped IPv6 (::ffff:a.b.c.d), because Go's net.IP.To4() returns the embedded IPv4 for that form and the standard checks then fire. It does NOT block the other IPv4-in-IPv6 transition forms, because for those To4() returns nil and every net.IP classifier reports the wrapper as a normal global IPv6 address:
- NAT64 well-known prefix
64:ff9b::/96(RFC 6052):64:ff9b::a9fe:a9feembeds169.254.169.254. - IPv4-compatible
::a.b.c.d(RFC 4291):::a9fe:a9feembeds169.254.169.254. - 6to4
2002::/16(RFC 3056):2002:a9fe:a9fe::embeds169.254.169.254.
The fix is to canonicalize the resolved address to its embedded IPv4 before classification, symmetric to how IPv4-mapped addresses are already handled by To4(). The same gap was fixed correctly in a sibling project: makeplane/plane apps/api/plane/utils/ip_address.py _embedded_ipv4() decodes IPv4-mapped, 6to4, Teredo and NAT64 before classifying; Cloudreve's guard is the unpatched twin of that pattern.
Severity
An authenticated low-privilege user can force the server to fetch attacker-chosen internal URLs and read the responses, including cloud instance-metadata credentials, producing a scope change from the download subsystem to the internal network and the host's cloud identity.
Proof of concept
The guard file pkg/request/ssrf.go imports only the Go standard library, so ValidateExternalURL was compiled and called verbatim from tag 4.17.0. The remote-download workflow calls it as ValidateExternalURL(ctx, SrcUri, opt) with default options.
Direction 1 (shipped guard accepts the internal-embedding wrappers):
=== Cloudreve v4.17.0 ValidateExternalURL (shipped, unmodified) ===
[ACCEPTED] NAT64 -> 169.254.169.254 (cloud metadata) http://[64:ff9b::a9fe:a9fe]/latest/meta-data/
[ACCEPTED] NAT64 -> 127.0.0.1 (loopback) http://[64:ff9b::7f00:1]/
[ACCEPTED] NAT64 -> 10.0.0.1 (RFC1918) http://[64:ff9b::a00:1]/
[ACCEPTED] IPv4-compatible -> 169.254.169.254 http://[::a9fe:a9fe]/latest/meta-data/
[ACCEPTED] IPv4-compatible -> 127.0.0.1 http://[::7f00:1]/
[ACCEPTED] 6to4 -> encodes 169.254.169.254 …
- Record
GHSA-jvh5-97xg-v99f- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-697, CWE-918
- Updated
- 2026-11-02
OSVGO-2026-6572 No score
Cloudreve: SSRF guard bypass: checkIP does not decode IPv6-transition wrappers (NAT64, IPv4-compatible, 6to4) reaching internal and cloud-metadata addresses in github.com/cloudreve/Cloudreve
Cloudreve: SSRF guard bypass: checkIP does not decode IPv6-transition wrappers (NAT64, IPv4-compatible, 6to4) reaching internal and cloud-metadata addresses in github.com/cloudreve/Cloudreve
- Record
GO-2026-6572- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/cloudreve/Cloudreve/v4Go |
before 4.0.0-20260715072853-1c5cad6dec7e | 4.0.0-20260715072853-1c5cad6dec7e |
github.com/cloudreve/CloudreveGo |
All versions | None known |
github.com/cloudreve/Cloudreve/v3Go |
All versions | None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-79913 is a medium vulnerability (CVSS 6.5) in Cloudreve, published September 22, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.40%, the 34th percentile. Fixed in github.com/cloudreve/Cloudreve/v4 4.0.0-20260715072853-1c5cad6dec7e.
References
github.com/cloudreve/cloudreve/security/advisories/GHSA-jvh5-97xg-v99f
github.com/cloudreve/cloudreve/commit/1c5cad6dec7ec3037c6479e3a26a3909995d16a2
github.com/cloudreve/cloudreve/releases/tag/4.18.0
nvd.nist.gov/vuln/detail/CVE-2026-79913
github.com/advisories/GHSA-jvh5-97xg-v99f
github.com/CVEProject/cvelistV5/tree/main/cves/2026/79xxx/CVE-2026-79913.json
github.com/cloudreve/cloudreve
Left out here: the rest of 2 source descriptions. The JSON record has them.