GitHub Advisoryadvisory · Go
GHSA-p6m2-r3w9-mpxw rclone local: crafted Range request against a translated symlink panics (DoS)
MEDIUM
Official page ↗
- Aliases
- CVE-2026-88015
- Ecosystem
- Go
- Packages
- github.com/rclone/rclone
- Severity
- Moderate
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
- Weaknesses
- CWE-190, CWE-248
- Reviewed
- 2026-09-10
Affected packages
• Go github.com/rclone/rclone: < 1.75.1 → fixed in 1.75.1
Description
Summary
When `backend/local` is used with `--links`/`-l` (or the `links=true` config option), each symlink is exposed as an rclone object whose content is the target path string, suffixed `.rclonelink`. `Object.Open()` decodes an incoming `fs.RangeOption` via `Decode(o.Size())`, then for a translated-symlink object passes the decoded `offset` straight into `openTranslatedLink`, which indexes the target string directly: `linkdst[offset:]`.
`RangeOption.Decode`'s `Start >= 0` branch (an ordinary `Range: bytes=X-` request) sets `offset = o.Start` with no upper bound, unlike its suffix-range branch (`Start = 0` branch never received the analogous protection.
A `Range: bytes=-` request sent to `rclone serve http`/`webdav` (or any consumer of `lib/http/serve`'s `Object()`, which parses and decodes the client's own Range header) against a directory containing a symlink therefore reaches `linkdst[offset:]` with offset far beyond the target string's length, and Go panics with "slice bounds out of range" instead of returning an empty read.
Details
Vulnerable code (before fix):
```go
func (o *Object) openTranslatedLink(offset, limit int64) (lrc io.ReadCloser, err error) {
linkdst, err := os.Readlink(o.path)
if err != nil { return nil, err }
return readers.NewLimitedReadCloser(io.NopCloser(strings.NewReader(linkdst[offset:])), limit), nil
}
```
PoC
Called the real production `Object.Open()` on a translated-symlink object (target length 12) with `&fs.RangeOption{Start: math.MaxInt64, End: -1}`:
```
panic: runtime error: slice bounds out of range [9223372036854775807:8]
...backend/local.(*Object).openTranslatedLink
...backend/local.(*Object).Open
```
Impact
A remote client can send a single crafted `Range` header against any symlink-backed object exposed by `rclone serve http`/`webdav`/etc (backed by `backend/local` with `--links` enabled) to deterministically panic the request-handling goroutine. Go's `net/http` recovers panics per-connection by default, so this fails the one request/connection rather than crashing the whole server process, and no file handle is left open (the panic occurs before any read handle is acquired) - but it is fully deterministic and remotely triggerable with no authentication or race window needed, unlike some other panic-recovery findings.
Fix
Clamp `offset` to the length of the target string before slicing, matching how a real file read past EOF behaves (an empty read):
```go
if offset > int64(len(linkdst)) {
offset = int64(len(linkdst))
}
```
Note: the shared `RangeOption.Decode()` also has a related, unaddressed issue - `limit = o.End - o.Start + 1` can itself overflow to a large negative number for a huge `End` - but a fix attempted there during this investigation broke `fs/operations/reopen.go`'s `NewReOpen`, which calls `Decode` with its `h.end` field still at its zero value at that point in construction. Flagged for awareness but not changed here to keep this patch minimal and low-risk.
Related
Alias · CVE (1)
- CVE-2026-88015 rclone is a command-line program to sync files and directories to and from different cloud storage providers. vulnerability
References
- https://github.com/rclone/rclone/security/advisories/GHSA-p6m2-r3w9-mpxw web
- https://nvd.nist.gov/vuln/detail/CVE-2026-88015 advisory
- https://github.com/rclone/rclone/commit/28bf49d66f94acc3f4f7f318504a706686281af9 web
- https://github.com/rclone/rclone package
- https://github.com/rclone/rclone/releases/tag/v1.75.1 web