Описание
RustFS has SourceIp bypass via spoofed X-Forwarded-For/Real-IP headers
Summary
IP-based access control can be bypassed: get_condition_values trusts client-supplied X-Forwarded-For/X-Real-Ip without verifying a trusted proxy, so any reachable client can spoof aws:SourceIp and satisfy IP-allowlist policies.
Details
- Vulnerable code:
rustfs/src/auth.rs:289-304setsremote_addrfromX-Forwarded-For/X-Real-Ip, then insertsSourceIpviaget_source_ip_raw, with no trust boundary or proxy validation:let remote_addr = header.get("x-forwarded-for").and_then(...).or_else(|| header.get("x-real-ip")...).unwrap_or("127.0.0.1");args.insert("SourceIp", vec![get_source_ip_raw(header, remote_addr)]);
- This value feeds IAM/bucket policy evaluation in
rustfs/src/storage/access.rs(authorization path), so any request that forges the header can meetaws:SourceIpconditions. - No authentication is required beyond the request itself; the header is taken at face value even on direct connections.
PoC
rustfs-auth-trusted-ip-header-spoofing-poc.tar.gz
Steps (already included in rustfs-auth-trusted-ip-header-spoofing-poc/):
- Start RustFS with two local volumes, e.g.:
- From
rustfs-auth-trusted-ip-header-spoofing-poc/, run:
Impact
- Vulnerability type: Authorization bypass of IP-allowlist (
aws:SourceIp) via header spoofing. - Who is impacted: Any deployment relying on
aws:SourceIpin IAM/bucket policies for S3 operations. Attackers with network reach to RustFS can forge forwarded-IP headers to gain list/read/write where IP restrictions were meant to block them.
Credits
Identified by SecMate (https://secmate.dev) automated analysis and validated during manual triage.
Пакеты
rustfs
< 1.0.0-alpha.78
1.0.0-alpha.78
Связанные уязвимости
RustFS is a distributed object storage system built in Rust. Prior to version alpha.78, IP-based access control can be bypassed: get_condition_values trusts client-supplied X-Forwarded-For/X-Real-Ip without verifying a trusted proxy, so any reachable client can spoof aws:SourceIp and satisfy IP-allowlist policies. This issue has been patched in version alpha.78.