VYPR
Critical severity9.8NVD Advisory· Published May 28, 2026

CVE-2026-45039

CVE-2026-45039

Description

RustFS is a distributed object storage system built in Rust. Prior to 1.0.0-beta.2, the internode RPC layer authenticates every request with an HMAC-SHA256 signature using a shared secret. The function that produces this secret, get_shared_secret() in crates/ecstore/src/rpc/http_auth.rs, falls back to the public, source-tree-embedded DEFAULT_SECRET_KEY = "rustfsadmin" when neither the RUSTFS_RPC_SECRET environment variable nor the global S3 secret key has been configured. This vulnerability is fixed in 1.0.0-beta.2.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

RustFS internode RPC HMAC secret falls back to hardcoded default 'rustfsadmin', allowing peer impersonation by any attacker reaching the RPC port.

Vulnerability

RustFS distributed object storage prior to version 1.0.0-beta.2 contains a hardcoded default credential vulnerability in its internode RPC authentication. The function get_shared_secret() in crates/ecstore/src/rpc/http_auth.rs falls back to the public, source-tree-embedded DEFAULT_SECRET_KEY = "rustfsadmin" when neither the RUSTFS_RPC_SECRET environment variable nor the global S3 secret key has been configured [1]. This affects all versions up to and including 1.0.0-beta.1.

Exploitation

An attacker who can reach the RPC port of a RustFS node can construct valid HMAC-SHA256 signatures using the known default secret "rustfsadmin". No authentication or prior access is required. The attacker can then impersonate a peer node, sending arbitrary RPC requests that will be accepted as legitimate by other cluster members [1]. The vulnerability is trivially exploitable because the default secret is publicly available in the source code.

Impact

Successful exploitation allows an attacker to impersonate any peer node in the RustFS cluster. This can lead to unauthorized data access, data manipulation, or denial of service, depending on the RPC operations performed. The impact is critical (CVSS 9.8) as it compromises the integrity and confidentiality of the entire distributed storage system without requiring any privileges [1].

Mitigation

The vulnerability is fixed in version 1.0.0-beta.2 [1]. Users should upgrade to this version or later. As a workaround, ensure that either the RUSTFS_RPC_SECRET environment variable or the global S3 secret key is explicitly configured to a strong, non-default value before starting the cluster. No other mitigations are available.

AI Insight generated on May 28, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2
  • Rustfs/Rustfsinferred2 versions
    <1.0.0-beta.2+ 1 more
    • (no CPE)range: <1.0.0-beta.2
    • (no CPE)range: <1.0.0-beta.2

Patches

0

No patches discovered yet.

Vulnerability mechanics

Root cause

"The `get_shared_secret()` function falls back to a public, source-tree-embedded default HMAC key (`DEFAULT_SECRET_KEY = "rustfsadmin"`) when no explicit RPC secret is configured, allowing any network-reachable attacker to forge valid internode RPC signatures."

Attack vector

An attacker who can reach the RPC port of any node in a RustFS cluster can forge valid HMAC-SHA256 signatures using the publicly known default secret `"rustfsadmin"` [ref_id=1]. The attacker constructs an HTTP request to any internode RPC endpoint (e.g., `/rustfs/rpc/list_disks`), computes the HMAC over the path, method, and timestamp using the default key, and sends it with the `x-rustfs-signature` and `x-rustfs-timestamp` headers [ref_id=1]. The server's `verify_rpc_signature` function compares the HMAC against `get_shared_secret()`, which returns `"rustfsadmin"` on a stock deployment, so the forged request is accepted as legitimate [ref_id=1]. No authentication, network position, or prior access is required beyond network reachability to the RPC port [CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H].

Affected code

The vulnerability resides in `crates/ecstore/src/rpc/http_auth.rs:33-44` in the `get_shared_secret()` function, which falls back to the hard-coded `DEFAULT_SECRET_KEY = "rustfsadmin"` when neither the `RUSTFS_RPC_SECRET` environment variable nor the global S3 secret key is configured [ref_id=1]. The same fallback chain exists in `crates/credentials/src/credentials.rs:219-226` in `get_rpc_token()` [ref_id=1]. Both the signer (`gen_signature_headers`, line 70) and verifier (`verify_rpc_signature`, line 88) call `get_shared_secret()`, so they agree on the fallback secret [ref_id=1].

What the fix does

The proposed fix removes the fallback to `DEFAULT_SECRET_KEY` from `get_shared_secret()` and instead panics at startup if neither `RUSTFS_RPC_SECRET` nor a non-default `RUSTFS_SECRET_KEY` is configured [ref_id=1]. The same change is applied to `get_rpc_token()` in `crates/credentials/src/credentials.rs` [ref_id=1]. Additionally, the fix refuses to bind non-loopback listeners when default credentials are in use, unless the operator explicitly opts in with `RUSTFS_ALLOW_DEFAULT_CREDENTIALS=1` [ref_id=1]. The advisory notes that the preferred long-term fix is first-run credential generation, persisting a random root credential pair to a config file with mode 0600 [ref_id=1]. The fix is applied in version 1.0.0-beta.2.

Preconditions

  • configRustFS cluster started without RUSTFS_RPC_SECRET environment variable and without overriding RUSTFS_SECRET_KEY (i.e., out-of-the-box configuration)
  • networkAttacker must have network reachability to the RPC port of any node in the cluster
  • authNo authentication or prior access required

Reproduction

Start a two-node cluster from the published binary with `RUSTFS_VOLUMES` pointing at two endpoints (e.g., `http://node1:7000`, `http://node2:7000`) and no other env vars [ref_id=1]. From a third host reachable to `node1:7000`, run the following Python script to sign and submit an internode RPC request using `"rustfsadmin"` as the HMAC key [ref_id=1]:

```python import base64, hmac, hashlib, time, urllib.request

SECRET = b"rustfsadmin" NODE = "http://node1:7000" PATH = "/rustfs/rpc/list_disks" METHOD = "GET"

ts = int(time.time()) msg = f"{PATH}|{METHOD}|{ts}".encode() sig = base64.b64encode(hmac.new(SECRET, msg, hashlib.sha256).digest()).decode()

req = urllib.request.Request(NODE + PATH, method=METHOD, headers={ "x-rustfs-signature": sig, "x-rustfs-timestamp": str(ts), }) print(urllib.request.urlopen(req, timeout=5).read()) ```

The server accepts the signature and processes the RPC call because the verifier compares against `get_shared_secret()`, which equals `"rustfsadmin"` on a stock deployment [ref_id=1].

Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

1

News mentions

0

No linked articles in our index yet.