GHSA-FC6G-2GCP-2QRQ

Vulnerability from github – Published: 2026-02-03 17:31 – Updated: 2026-02-03 18:55
VLAI?
Summary
RustFS has SourceIp bypass via spoofed X-Forwarded-For/Real-IP headers
Details

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-304 sets remote_addr from X-Forwarded-For/X-Real-Ip, then inserts SourceIp via get_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 meet aws:SourceIp conditions.
  • 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/):

  1. Start RustFS with two local volumes, e.g.:
     mkdir -p /tmp/rustfs-data1 /tmp/rustfs-data2
     RUSTFS_ACCESS_KEY=devadmin RUSTFS_SECRET_KEY=devadmin \
       cargo run --bin rustfs -- --address 0.0.0.0:9000 \
       /tmp/rustfs-data1 /tmp/rustfs-data2
  1. From rustfs-auth-trusted-ip-header-spoofing-poc/, run:
     ENDPOINT=http://127.0.0.1:9000 make run
 The script:
  - Creates bucket `rustfs-trusted-ip-poc`.
  - Applies a bucket policy allowing `s3:ListBucket` only from `10.0.0.5/32` (`Principal: {"AWS":["*"]},` Resource array).
  - Sends three unauthenticated `ListBucket` calls:
      - Baseline (no spoof) → HTTP 403.
      - Spoofed `X-Forwarded-For: 10.0.0.5` → HTTP 200 (policy bypass).
      - Spoofed `X-Forwarded-For: 1.2.3.4` → HTTP 403.
  - Responses saved to `poc-baseline.xml`, `poc-spoofed.xml`, `poc-deny.xml`.

Impact

  • Vulnerability type: Authorization bypass of IP-allowlist (aws:SourceIp) via header spoofing.
  • Who is impacted: Any deployment relying on aws:SourceIp in 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.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "crates.io",
        "name": "rustfs"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.0.0-alpha.78"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-21862"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-290"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-02-03T17:31:41Z",
    "nvd_published_at": "2026-02-03T16:16:12Z",
    "severity": "HIGH"
  },
  "details": "### Summary\nIP-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.\n\n### Details\n\n  - Vulnerable code: `rustfs/src/auth.rs:289-304` sets `remote_addr` from `X-Forwarded-For`/`X-Real-Ip`, then inserts `SourceIp` via\n    `get_source_ip_raw`, with no trust boundary or proxy validation:\n      - `let remote_addr = header.get(\"x-forwarded-for\").and_then(...).or_else(|| header.get(\"x-real-ip\")...).unwrap_or(\"127.0.0.1\");`\n      - `args.insert(\"SourceIp\", vec![get_source_ip_raw(header, remote_addr)]);`\n  - This value feeds IAM/bucket policy evaluation in `rustfs/src/storage/access.rs` (authorization path), so any request that forges the header can meet `aws:SourceIp` conditions.\n  - No authentication is required beyond the request itself; the header is taken at face value even on direct connections.\n\n\n### PoC\n\n[rustfs-auth-trusted-ip-header-spoofing-poc.tar.gz](https://github.com/user-attachments/files/24038162/rustfs-auth-trusted-ip-header-spoofing-poc.tar.gz)\n\n\nSteps (already included in `rustfs-auth-trusted-ip-header-spoofing-poc/`):\n\n  1. Start RustFS with two local volumes, e.g.:\n\n```\n     mkdir -p /tmp/rustfs-data1 /tmp/rustfs-data2\n     RUSTFS_ACCESS_KEY=devadmin RUSTFS_SECRET_KEY=devadmin \\\n       cargo run --bin rustfs -- --address 0.0.0.0:9000 \\\n       /tmp/rustfs-data1 /tmp/rustfs-data2\n```\n\n  2. From `rustfs-auth-trusted-ip-header-spoofing-poc`/, run:\n\n```\n     ENDPOINT=http://127.0.0.1:9000 make run\n```\n\n     The script:\n      - Creates bucket `rustfs-trusted-ip-poc`.\n      - Applies a bucket policy allowing `s3:ListBucket` only from `10.0.0.5/32` (`Principal: {\"AWS\":[\"*\"]},` Resource array).\n      - Sends three unauthenticated `ListBucket` calls:\n          - Baseline (no spoof) \u2192 HTTP 403.\n          - Spoofed `X-Forwarded-For: 10.0.0.5` \u2192 HTTP 200 (policy bypass).\n          - Spoofed `X-Forwarded-For: 1.2.3.4` \u2192 HTTP 403.\n      - Responses saved to `poc-baseline.xml`, `poc-spoofed.xml`, `poc-deny.xml`.\n\n\n### Impact\n\n  - Vulnerability type: Authorization bypass of IP-allowlist (`aws:SourceIp`) via header spoofing.\n  - Who is impacted: Any deployment relying on `aws:SourceIp` in 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.\n\n### Credits\nIdentified by SecMate (https://secmate.dev) automated analysis and validated during manual triage.",
  "id": "GHSA-fc6g-2gcp-2qrq",
  "modified": "2026-02-03T18:55:45Z",
  "published": "2026-02-03T17:31:41Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/rustfs/rustfs/security/advisories/GHSA-fc6g-2gcp-2qrq"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-21862"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rustfs/rustfs/commit/b4ba62fa3300b5b258fdc0da141481e3be7ea960"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/rustfs/rustfs"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:P",
      "type": "CVSS_V4"
    }
  ],
  "summary": "RustFS has SourceIp bypass via spoofed X-Forwarded-For/Real-IP headers"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…