Sep 11, 2026·7 min read·16 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 |
An authorization bypass vulnerability in Vikunja's link share deletion handlers allows project members with Write privileges to delete Admin-tier link shares. The handler passes an unpopulated struct to the authorization check, causing the permission evaluation to fall back to default Write permissions instead of requiring Admin privileges.
Vikunja versions 2.2.0 through 2.6.0 contain a Cross-Origin Resource Sharing (CORS) misconfiguration flaw in `code.vikunja.io/api`. Default configurations permit wildcard origins for localhost (`http://127.0.0.1:*` and `http://localhost:*`) with credentialed requests (`Access-Control-Allow-Credentials: true`). Because configuring a public service URL appends to this default list rather than overriding it, production environments inadvertently trust all local origins. A local page or application on a user's machine can execute a credentialed cross-origin request to the token refresh endpoint, extract the returned JWT access token, and achieve complete account takeover.
An insufficient session invalidation vulnerability exists in pyLoad (pyload-ng) versions 0.5.0b3.dev98 through 0.5.0b3.dev101. When administrative actions like privilege revocation or password changes are executed via the public REST API, active user sessions on disk are not updated or invalidated. Consequently, affected sessions remain fully authenticated with stale permissions for up to 31 days.
A critical security vulnerability has been identified and patched in the WebUI component of pyLoad, a popular Python-based open-source download manager. This vulnerability allows attackers to completely bypass API rate limits and spoof client IP addresses in audit logs due to unsafe parsing of the X-Forwarded-For HTTP header.
An authorization bypass and credential oracle vulnerability in pyload-ng allows authenticated users with minimal or no privileges to brute-force the administrator password. This is achieved through sensitive API methods exposed globally combined with a non-constant-time password hash comparison algorithm.
An authentication bypass vulnerability in pyLoad allows unauthenticated remote attackers to gain administrative API access. The vulnerability is caused by a logical flaw in the API key cache validation lookup, where authentication states are cached using only the public key identifier, skipping cryptographic token verification on cache hits.