Feb 3, 2026·6 min read·36 visits
RustFS versions alpha.13 through alpha.81 logged full S3 credentials (access/secret keys) in plaintext at the INFO log level. Attackers with access to logs (Splunk, ELK, local disk) can compromise the entire storage cluster. Patch to alpha.82 immediately and rotate all keys.
RustFS, a high-performance distributed object storage system, inadvertently implemented a feature that turns your log aggregation stack into a password manager. By logging authentication credentials at the INFO level, the system broadcasted Access Keys, Secret Keys, and Session Tokens to anyone with read access to the system logs.
We love Rust. It saves us from double-frees, dangling pointers, and the nightmares of C++ memory management. But here's the kicker: the compiler can prevent you from writing to unallocated memory, but it can't prevent you from writing your secrets to stdout. That is exactly what happened with RustFS.
RustFS is designed to be a high-performance, S3-compatible object storage layer. It's the kind of thing you deploy when you want to handle petabytes of data without the overhead of the JVM. It handles authentication, data replication, and distribution. It holds the keys to the kingdom—literally.
CVE-2026-24762 isn't a complex buffer overflow or a race condition that requires nanosecond precision. It is the digital equivalent of a bank manager shouting the vault combination across the lobby every time they open it. For nearly 70 versions (alpha.13 to alpha.81), RustFS decided that Access Keys, Secret Keys, and Session Tokens were just mundane strings worthy of the INFO log level.
The root cause here is a classic developer convenience feature turning into a security liability. In Rust, we frequently use #[derive(Debug)] on structs to automatically generate code that can format the struct for output. It's fantastic for development. You want to see what's in your User object? Just println!("{:?}", user).
However, when you apply this indiscriminately to structs containing sensitive data, Debug does exactly what you asked it to do: it prints everything. The developers likely had a struct handling S3 credentials and, innocently enough, derived Debug on it. Then, somewhere in the authentication flow, they added a logging statement like info!("Authenticating request: {:?}", credentials).
The result? Every time a client authenticated, their full credentials were serialized into the application logs. Since this was done at INFO level—which is the default in almost every production environment—these secrets weren't just staying on the machine. They were being shipped to Datadog, Splunk, ELK, and CloudWatch, effectively creating a searchable database of valid API keys.
Let's look at a reconstruction of the offending pattern. This is a common anti-pattern in Rust web services.
The Vulnerable Code (Simplification):
// The struct holds critical secrets
#[derive(Debug, Clone)] // <--- The culprit
pub struct S3Credentials {
pub access_key: String,
pub secret_key: String,
pub session_token: Option<String>,
}
fn authenticate(creds: &S3Credentials) {
// This looks helpful for debugging connection issues...
// But it dumps the secret_key in plaintext to logs.
log::info!("Processing auth for: {:?}", creds);
// ... processing logic
}When this runs, your logs fill up with:
[INFO] Processing auth for: S3Credentials { access_key: "AKIA...", secret_key: "wJalr...", session_token: None }
The Fix (Proper Trait Implementation):
To fix this, you must manually implement Debug (or Display) to redact sensitive fields, rather than deriving it automatically.
impl fmt::Debug for S3Credentials {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("S3Credentials")
.field("access_key", &self.access_key)
.field("secret_key", &"[REDACTED]") // <--- Safe now
.field("session_token", &"[REDACTED]")
.finish()
}
}This change ensures that even if a developer blindly logs the struct, the output remains safe.
Exploiting this requires zero technical sophistication regarding the RustFS binary itself. You don't need a debugger, you don't need shellcode, and you don't need to bypass ASLR. You just need access to the logs. This is often easier than gaining root access to the server itself. Log aggregators are frequently shared across teams with overly permissive read access.
Attack Scenario:
grep -r "secret_key" /var/log/rustfs/
# OR in Kibana:
service:rustfs AND message:"secret_key"The beauty (and horror) of this exploit is that it works historically. If you rotate the logs but not the keys, the attacker can mine data from six months ago and still likely find valid credentials.
The impact here is Complete Compromise of Data Confidentiality and Integrity. In object storage systems, the Access/Secret key pair is the ultimate authority.
With these keys, an attacker can:
DeleteObject or DeleteBucket commands. Ransomware gangs love this—exfiltrate the data, delete the originals, demand payment.Since INFO logs are voluminous, they are often retained for weeks or months. This vulnerability creates a massive window of exposure where every single successful authentication event was recorded.
Patching the software is only step one. Upgrading to RustFS alpha.82 stops the bleeding—it stops new logs from containing secrets. However, it does nothing about the gigabytes of text files already sitting on your disk or in your cloud logging provider.
Your Remediation Checklist:
alpha.82 immediately.sed -i 's/secret_key: ".*"/secret_key: "[REDACTED]"/g' /var/log/rustfs.log. Do this on your log servers, backups, and SIEM.N months (where N is your log retention period) is compromised. Issue new Access Keys and revoke the old ones.CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
RustFS rustfs | >= alpha.13, < alpha.82 | alpha.82 |
| Attribute | Detail |
|---|---|
| CWE | CWE-532 (Insertion of Sensitive Info into Log File) |
| CVSS v4.0 | 6.9 (Medium) |
| Attack Vector | Network (Log Access) |
| Exploit Complexity | Low |
| Data Leaked | Access Keys, Secret Keys, Session Tokens |
| Patch Status | Fixed in alpha.82 |
The product writes sensitive information to log files, which can be read by anyone with access to the logs.
CVE-2026-48861 is a client-side HTTP request-line CRLF (Carriage Return Line Feed) injection vulnerability in the popular Elixir HTTP client library, Mint. The vulnerability permits HTTP Request Splitting and HTTP Request Smuggling when an application forwards untrusted, attacker-controlled inputs to Mint's HTTP client requests as either the HTTP request method or target. By embedding CRLF characters within these parameters, an attacker can terminate the request line prematurely, inject malicious headers, or pipeline entirely independent requests. These smuggled requests are then processed by upstream or downstream proxy servers as separate HTTP queries on the same TCP connection. While Mint version 1.7.0 introduced target validation to secure the request target, the HTTP request method parameter remained completely unvalidated. This flaw allows attackers to bypass routing filters, access restricted internal APIs, or poison HTTP caches under default configurations.
An Inconsistent Interpretation of HTTP Requests (HTTP Request/Response Smuggling) vulnerability in the Elixir Mint HTTP client allows attacker-controlled HTTP/1 servers to desynchronize response framing on shared connections due to over-lenient parsing of sign-prefixed Content-Length headers.
An allocation of resources without limits or throttling vulnerability in Elixir Mint allows an attacker-controlled HTTP/2 server to exhaust memory in a Mint client. The vulnerability is exploited by sending a HEADERS frame without the END_HEADERS flag followed by an infinite stream of CONTINUATION frames. Because the client lacks limits on the incoming header-block accumulator, the client continuously consumes memory until an out-of-memory crash occurs.
CVE-2026-48596 is an Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting, CWE-113) in the Elixir Tesla HTTP client. The flaw resides in how multipart content-type parameters are joined and serialized, enabling attackers to inject arbitrary headers or split HTTP requests when applications pass untrusted inputs to the parameters of multipart uploads.
An improper handling of highly compressed data (decompression bomb) vulnerability exists in the Elixir Tesla HTTP client when utilizing response decompression middlewares. By serving highly compressed responses or stacked content-encoding headers, a malicious server can cause arbitrary heap exhaustion, leading to a denial of service (DoS) crash in the BEAM virtual machine.
A high-severity security vulnerability in Elixir's Tesla HTTP client library (CVE-2026-48595) allows unauthenticated remote attackers to harvest sensitive credentials, including Authorization headers and cookies. The flaw resides in the 'Tesla.Middleware.FollowRedirects' component, which performs case-sensitive lookups when stripping credentials during cross-origin redirects. Because HTTP headers are case-insensitive by RFC specifications, standard canonical casing (e.g., 'Authorization') bypasses the lowercase-only blocklist, leaking tokens to untrusted external redirect destinations.