GitHub Security Advisory: GHSA-mm2q-qcmx-gw4w
Package: rustfs (RUST)
Severity: HIGH (CVSS 0.0)
CWE: CWE-863: Incorrect Authorization
Vulnerable versions: <= 1.0.0-alpha.91
Patched in: 1.0.0-alpha.98

Summary: RustFS: ListServiceAccount authorizes against wrong admin action, enabling cross-user enumeration and root service account takeover

Details:
## Summary

`ListServiceAccount` (`GET /rustfs/admin/v3/list-service-accounts?user=<other>`) authorizes cross-user requests against `UpdateServiceAccountAdminAction` instead of `ListServiceAccountsAdminAction` at `rustfs/src/admin/handlers/service_account.rs:936`. The handler accepts the **wrong** admin action and rejects the **correct** one:

- A user granted only `admin:UpdateServiceAccount` enumerates every service account in the cluster, including the root user's (HTTP 200, full metadata).
- A user granted only `admin:ListServiceAccounts` — the permission name every IAM document treats as "list service accounts" — receives HTTP 403 AccessDenied on the same request.

Because service account access keys act as the identifier a `UpdateServiceAccount` holder needs to rotate a secret, and the `UpdateServiceAccount` handler at `rustfs/src/admin/handlers/service_account.rs:489` performs no ownership check on the target access key, leaking those access keys lets a delegated "service account updater" role overwrite `root-sa-1`'s secret, authenticate as the root user's service account, and create a persistent backdoor admin with `admin:*` + `s3:*`. Proven live end-to-end against `rustfs/rustfs:latest` (1.0.0-alpha.91, revision `d4ea14c2`) — the same revision is byte-identical on current `origin/main`.

## Vulnerability Details

- **Package:** `rustfs` (binary crate `rustfs`)
- **Affected versions:** From `0a2411f` (the initial `service_account.rs` check-in on 2026-03-15) through current HEAD `90e584a`. The vulnerable line has never been touched.
- **Fixed versions:** None
- **Vulnerable file:** `rustfs/src/admin/handlers/service_account.rs`
- **Vulnerable route:** `GET /rustfs/admin/v3/list-service-accounts?user=<other_user>` (`ListServiceAccount::call`)
- **CWE:** CWE-863 (Incorrect Authorization), chained with CWE-620 (Unverified Password Change) to reach CWE-269 (Improper Privilege Management)
- **CVSS (demonstrated chain to full admin):** `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H` = **10.0 Critical**. If scored as Scope:Unchanged the vector is `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H` = **8.8 High**. The list bug alone (no chain) is `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N` = **6.5 Medium** and is what a maintainer would rate it if the Update ownership gap is out of scope for this report.

## Two Distinct Vulnerabilities

This report documents two bugs that chain to full RustFS administrative takeover. Each is independently fixable and independently a security issue:

**Vulnerability A — Wrong action constant in ListServiceAccount (CWE-863)**
`ListServiceAccount::call` at line 936 checks `UpdateServiceAccountAdminAction` instead of `ListServiceAccountsAdminAction`. This is a copy-paste typo: the three sibling list handlers (lines 658, 799, 1095) all use the correct constant. The result is a permission inversion — the correct permission (`admin:ListServiceAccounts`) is rejected, and the wrong one (`admin:UpdateServiceAccount`) is accep