GHSA-945v-v9p3-v5xw: Low severity go/github.com/rclone/rclone vulnerability

Published Aug 5, 2026
·
Updated

Summary When writing an object with metadata, the local backend applies the source-supplied mode, uid, and gid verbatim: it parses mode as an octal integer and passes it straight into os.Chmod(o.path, os.FileMode(umode)), and passes uid/gid straight into os.Chown. The value is never masked to permission bits, so any value with Go's ModeSetuid (1<<23) or ModeSetgid (1<<22) bit set causes the setuid/setgid bit to be applied. Because both the file content and its metadata come from the (attacker-controlled) source remote, an attacker stores a binary of their choosing with mode = 40000755 (and uid = 0); when the victim runs rclone copy -M <remote>: /dest, rclone writes the attacker's binary and makes it setuid. If the victim runs rclone as root (typical for system backup/restore), the uid=0 chown plus setuid produces a root-owned setuid binary with attacker content — any local user then escalates to root. When rclone runs as a non-root service user, the planted setuid binary is owned by that user, giving any local user that user's privileges (lateral escalation / persistent backdoor).

Details backend/local/metadata.go, writeMetadataToFile(): go uid, hasUID := o.parseMetadataInt(m, "uid", 10) gid, hasGID := o.parseMetadataInt(m, "gid", 10) if hasUID { ... err = os.Chown(o.path, uid, gid) // source-controlled owner, no same-uid guard } mode, hasMode := o.parseMetadataInt(m, "mode", 8) if hasMode && mode >= 0 { umode := uint(mode) if umode <= math.MaxUint32 { err = os.Chmod(o.path, os.FileMode(umode)) // <-- raw value; ModeSetuid/ModeSetgid NOT masked off } } os.Chmod/os.FileMode honor ModeSetuid/ModeSetgid/ModeSticky. There is no &^ (os.ModeSetuid|os.ModeSetgid) mask and no check that the source is trusted, so an attacker-chosen mode string sets those bits on the freshly written, attacker-controlled file. (Note: a legitimate local source reports mode in unix stmode layout e.g. 0106755, whose bit 1<<23 is unset, so honest copies happen to drop setuid — but the attacker supplies the Go-FileMode layout 40000755 directly, which sets it.)

PoC 1) Get the official stable binary: curl -fsSLO https://downloads.rclone.org/v1.74.3/rclone-v1.74.3-linux-amd64.zip unzip -j rclone-v1.74.3-linux-amd64.zip '/rclone' -d . # ./rclone -> v1.74.3 2) Create a payload (the attacker-controlled binary content) and copy it with the malicious mode metadata: mkdir -p msrc mdst && cp /bin/true msrc/payload ./rclone copy -M --metadata-set mode=40000755 msrc mdst # 40000755 = Go FileMode setuid|0755 3) Observe — the destination file is now setuid: stat -c '%A %a' mdst/payload -rwsr-xr-x 4755 # 's' = setuid bit SET on attacker binary Variants: mode=20000755 → setgid (-rwxr-sr-x); mode=60000755 → both (-rwsr-sr-x). With rclone run as root and the source object also carrying uid=0/gid=0, the file is chown'd root:root, yielding a root-owned setuid binary executable by any local user.

Impact A victim performing a metadata-preserving copy/restore (-M) from an untrusted or compromised remote installs an attacker-chosen executable with the setuid/setgid bit set. Run as root (system backup/restore, the common case for --metadata), this is a root-owned setuid root backdoor executable by any local user → local privilege escalation to root. Run as a non-root user, it is a setuid backdoor for that service account. The companion uid/gid application lets a root-run transfer also reassign ownership of written files arbitrarily.

Remediation Mask special bits before applying mode from metadata — os.Chmod(o.path, os.FileMode(umode).Perm()) (or umode & 0o777) — and do not honor setuid/setgid/sticky from source metadata; gate uid/gid/setuid application behind an explicit opt-in (e.g. --local-metadata-set-ownership) that is off by default, and document that -M from untrusted remotes must not restore privileged bits. Regression test: copying an object with mode=40000755/uid=0 must produce a non-setuid, caller-owned file unless the opt-in is set.

Affected Software

1 affected componentFixes available
go/github.com/rclone/rclone<=1.74.3
1.74.4

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade go/github.com/rclone/rclone to a version that resolves this vulnerability.

    Fixed in 1.74.4
  2. Upgrade

    Upgrade rclone to a version that resolves this vulnerability.

    Fixed in v1.74.3
  3. Configuration

    Modify writeMetadataToFile() so that when applying source-controlled metadata, rclone masks the parsed metadata mode to only permission bits before calling os.Chmod(o.path,...). Specifically, change raw os.Chmod(o.path, os.FileMode(umode)) to os.Chmod(o.path, os.FileMode(umode).Perm()) or to os.Chmod(o.path, os.FileMode(umode & 0o777)), so ModeSetuid/ModeSetgid/ModeSticky are not honored from untrusted metadata.

    rclone backend/local metadata (backend/local/metadata.go, writeMetadataToFile) metadata mode handling (mask special bits) = umode & 0o777 (or os.FileMode(umode).Perm())
  4. Configuration

    Do not apply source-controlled uid/gid verbatim from metadata. Gate uid/gid (and any setuid/setgid behavior) behind an explicit opt-in (e.g., only honor uid/gid/setuid bits when --local-metadata-set-ownership is enabled, and keep it off by default as described).

    rclone backend/local metadata (backend/local/metadata.go, writeMetadataToFile) metadata owner (uid/gid) application = disable unless explicit opt-in
  5. Configuration

    Ensure --local-metadata-set-ownership is kept off by default and document/ensure that using -M (metadata-preserving copy/restore) from untrusted remotes does not restore privileged bits like setuid/setgid or apply attacker-supplied ownership.

    rclone CLI / local metadata options --local-metadata-set-ownership = off by default
  6. Compensating control

    Run rclone restores/copies that use metadata (-M / --metadata) as a non-root user when possible, because if run as root the setuid/setgid plus uid=0/gid=0 metadata can plant a root-owned setuid backdoor for local privilege escalation.

Event History

Aug 5, 2026
Advisory Published
via GitHub·08:03 PM
Data Sourced
via GitHub·08:03 PM
DescriptionSeverityWeaknessAffected Software
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203