Sep 11, 2026·7 min read·0 visits
A global credential map in rclone's FTP auth-proxy driver allows an attacker sharing a generic username to hijack a victim's concurrent FTP session storage backend.
The FTP server implementation of rclone is vulnerable to a cross-session identity and credential confusion flaw when configured with an authentication proxy. Under specific multi-tenant configurations where multiple distinct sessions authenticate with the same username, a global map caches credentials globally instead of isolating them inside the session context. This allows a concurrent attacker to hijack the active session backend of a victim using the same username.
The rclone cloud storage utility includes an FTP server engine (serve ftp) that supports external authentication via an HTTP service or script when configured with the --auth-proxy command-line flag. This mechanism delegates credentials checking and dynamic Virtual File System (VFS) provisioning to an external service. In dynamic environments, this architecture allows administrators to host a unified FTP service that maps incoming users to isolated cloud storage containers or local directories on demand.
In versions 1.64.0 through 1.75.0, the implementation fails to isolate authentication credentials to individual connection contexts. When configured with the authentication proxy, the FTP server driver maintains user state at the server-wide level rather than the individual session level. This architectural oversight exposes an attack surface where sessions can overlap and modify global states belonging to separate clients.
Because the underlying driver uses a global cache to store credentials, active connections are subjected to session state manipulation if a second client connects under the same username. In enterprise configurations where multiple distinct customers or automated workflows authenticate with a generic username (e.g., "customer" or "api") but supply different passwords or tokens to resolve to isolated backends, this lack of session isolation leads to identity confusion.
The technical flaw is located within the FTP driver structure defined in cmd/serve/ftp/ftp.go. The state-holding driver structure uses a global map to cache the obscured passwords associated with usernames:
type driver struct {
f fs.Fs
srv *ftp.Server
ctx context.Context
opt Options
provider *proxy.Provider
useTLS bool
userPassMu sync.Mutex
userPass map[string]string // Cache of username => password
}The implementation uses the userPass map to retain the user's password for subsequent backend re-authorization queries. The lookup key is strictly the username string. This design assumes a one-to-one mapping between active usernames and credential lifecycles. However, when an FTP client invokes the CheckPasswd function, the driver processes the credentials through the external proxy provider and updates this global map.
func (d *driver) CheckPasswd(sctx *ftp.Context, user, pass string) (ok bool, err error) {
if d.provider.IsProxy() {
// ...
oPass, err := obscure.Obscure(pass)
if err != nil {
return false, err
}
d.userPassMu.Lock()
d.userPass[user] = oPass
d.userPassMu.Unlock()
}
}When any filesystem request occurs (such as downloading, uploading, or listing files), the driver invokes getVFS to retrieve the backend. The function queries the global userPass map using the active username. If a second user (the victim) logs in using the same username but a different password/token while the first session (the attacker) is still open, the second user's credentials overwrite the entry in the userPass map. Any subsequent filesystem command issued by the first user is evaluated using the second user's credentials, resulting in unauthorized cross-session access to the victim's backend storage.
The vulnerability was resolved in commit c6af0b57c2b4af848bc968c2b407354476184b99 by shifting credential storage from the global driver scope to the connection-specific metadata map provided by the FTP engine. The global userPass map and its associated mutex userPassMu were completely removed from the driver struct.
The patch leverages sctx.Sess.Data, a map local to the individual FTP session context *ftp.Context. The key differences in the login validation sequence are shown in the following diff:
@@ -327,17 +330,18 @@
fs.Infof(nil, "proxy login failed: %v", err)
return false, nil
}
- // Cache obscured password for later lookup.
+ // Cache the obscured password on the session for later lookup.
//
- // We don't cache the VFS directly in the driver as we want them
- // to be expired and the auth proxy does that for us.
+ // We don't cache the VFS directly as we want it to be expired and
+ // the auth proxy does that for us. We bind the credential to this
+ // FTP session rather than to the username so a later login with the
+ // same username but a different credential can't rebind this
+ // session's operations to a different backend.
oPass, err := obscure.Obscure(pass)
if err != nil {
return false, err
}
- d.userPassMu.Lock()
- d.userPass[user] = oPass
- d.userPassMu.Unlock()
+ sctx.Sess.Data[sessionObscuredPassKey] = oPass
}When a client attempts an operation, getVFS retrieves the credential strictly from the session metadata map rather than the shared map. Because of this architectural separation, a concurrent session login under an identical username will write to its own independent metadata store, preventing state contamination.
To exploit this flaw, an attacker must have network access to the rclone FTP port and possess valid credentials to authenticate successfully. The targeted system must be configured to use the --auth-proxy mechanism, and multiple tenants must connect using a shared or duplicate username structure.
The attack begins when the attacker establishes a legitimate connection to the FTP service with their credentials. The attacker verifies access to their storage and keeps the control connection open, sending standard keep-alive commands such as NOOP. While this session remains established, the attacker waits for a victim to connect.
When a victim logs in using the same username but different credentials, the server-side map overwrites the cached credential for that username string. The attacker then issues filesystem requests (e.g., LIST, RETR, or STOR). The server handles these requests by executing getVFS, pulling the victim's credentials from the global map, and reauthorizing the attacker's active session against the victim's storage root. This grants the attacker full read, write, and deletion privileges over the victim's data.
This vulnerability has a CVSS v3.1 base score of 7.3, representing a high-severity risk. The impact on confidentiality and integrity is high, as the attacker can download sensitive files, modify configurations, or write malicious files onto the victim's backend storage. The impact on availability is assessed as none, as exploiting the flaw does not crash the FTP service or disrupt the victim's network access, although it could lead to file deletion.
In multi-tenant cloud storage gateways, this vulnerability allows for complete cross-tenant isolation bypass. A malicious tenant can automate the attack by programmatically keeping their session alive and constantly checking the directory listing until the backend changes, indicating a new user has logged in. The attack does not require elevated administrative privileges to execute, only standard credentials.
The principal remediation is upgrading to rclone version 1.75.1 or newer. This release completely eliminates the global state caching model for authentication. If upgrading immediately is not possible, security administrators should apply operational workarounds.
First, configure the external authentication proxy to enforce unique usernames across all connecting tenants. This prevents any credential mapping overlap. Second, avoid exposing the FTP server utilizing the --auth-proxy option if identical usernames must be used in the environment. Third, restrict access to the FTP server port using a network firewall to limit connections strictly to trusted IP ranges.
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N| Attribute | Detail |
|---|---|
| CWE ID | CWE-488 (Exposure of Data Element to Wrong Session) |
| Attack Vector | Network |
| CVSS v3.1 Score | 7.3 (High) |
| Exploit Status | poc |
| KEV Status | Not Listed |
| Impact | Complete Cross-Session Information Disclosure and File Integrity Compromise |
CVE-2026-88046 (also tracked via GHSA-38xv-hf3p-h7mq) is a directory traversal and root confinement escape vulnerability residing in the core listing and transfer logic of rclone. Prior to version 1.75.1, raw relative parent-directory sequences returned by flat-keyspace source backends are trusted and processed without proper sanitization, enabling writes outside the designated target root or bucket.
An authentication bypass vulnerability exists in rclone when dynamically starting FTP, S3, or SFTP servers via the Remote Control (RC) 'serve/start' API. The server constructors incorrectly check the global process configuration rather than request-scoped options, resulting in a silent bypass of the authentication proxy and enabling unauthenticated access.
Prior to version 1.75.1, rclone's S3 server component ('rclone serve s3') contains an authentication bypass vulnerability when configured with '--auth-proxy' but without '--auth-key'. The application validates AWS Signature Version 4 (SigV4) against an empty secret key string, enabling unauthenticated remote attackers to access storage backends.
A request-level denial of service vulnerability exists in rclone versions prior to 1.75.1 when configured with local symlink virtualization (--links) and serving files over HTTP or WebDAV. An unauthenticated remote attacker can trigger a Go runtime slice bounds panic by sending a crafted HTTP Range request with an offset exceeding the path length of the target symlink.
rclone versions from 1.49.0 up to 1.75.1 are vulnerable to information disclosure and credential leakage. When configuring custom headers on HTTP connections, rclone fails to strip those headers when following HTTP redirects to external untrusted domains. Additionally, rclone does not prevent scheme downgrades from HTTPS to HTTP on same-host redirects, allowing sensitive standard credentials to be transmitted in cleartext.
A critical path traversal vulnerability (commonly known as 'Zip Slip') exists in rclone's ZIP archive backend implementation (backend/archive/zip/zip.go) between versions 1.72.0 and 1.75.1. The flaw allows an attacker to write arbitrary files outside the designated extraction directory by supplying a maliciously crafted ZIP archive. Additionally, the backend's directory boundary verification routine failed to enforce strict path limits, causing sibling folders sharing a name prefix to match incorrectly and leading to unauthorized data exposure. This issue has been fully resolved in version 1.75.1.