test(security): add GHSA-named regression tests for 3p3x and r5qv (backlog#1151 sec-6) Anchor the two fixed advisories to discoverable, named regression tests so `rg -i "ghsa|3p3x|r5qv"` finds a guard for each, and future fixes are forced to update pinned behavior (red -> green). GHSA-3p3x-734c-h5vx (constant-time WebDAV/FTPS secret comparison, rustfs#4403): - ftps_core.rs: new `assert_ftps_ghsa_3p3x_wrong_credentials_rejected` drives the `ct_eq` reject branch in FtpsAuthenticator::authenticate; asserts wrong password and unknown user are both rejected (530) and indistinguishable. - webdav_core.rs: the auth-failure block now sends a valid access key with a wrong secret (exercising the `ct_eq` branch, not just the unknown-access-key path) plus an unknown user, asserting both 401 and indistinguishable. - Module doc comments map advisory -> tests -> fix PR on both files. GHSA-r5qv-rc46-hv8q (internode RPC fail-closed, rustfs#4402): - http_auth.rs: renamed the default-fallback rejection test to `ghsa_r5qv_resolve_shared_secret_rejects_default_fallback` (and broadened it to cover default env secret + blank secrets), and added `ghsa_r5qv_verify_rpc_signature_fails_closed_on_missing_or_invalid_auth` pinning the exact advisory scenario (missing/forged/cross-URL signature is rejected; a correctly signed request still passes). File-level doc maps the advisory. Docs: new docs/testing/security-regressions.md with the advisory -> test mapping table and where each layer runs; linked from docs/testing/README.md. sec-14 will formalize the written policy in AGENTS.md. The unit-level ghsa_r5qv_* tests run in the default CI pass. The WebDAV/FTPS e2e live in the protocols suite (fixed ports, --test-threads=1); they cannot join the e2e-smoke profile and are wired into CI by sec-5. Refs: rustfs/backlog#1151 (sec-6), rustfs/backlog#1155
2.9 KiB
Security Advisory Regression Tests
Every fixed RustFS GitHub Security Advisory (GHSA) should map to at least one named, discoverable regression test. The convention is: name the test (or a helper / doc comment on the exact assertion) after the advisory so that
rg -i "ghsa|3p3x|r5qv"
finds the guard for any advisory, and a future fix of a still-open advisory is forced to update its pinned test (red -> green).
This is the lightweight inventory. sec-14 (backlog#1151) formalizes the written admission policy in
AGENTS.md; keep this file as the map.
Advisory -> test mapping
| Advisory | Class | Fix PR | Named regression tests | Layer |
|---|---|---|---|---|
| GHSA-3p3x-734c-h5vx | Constant-time secret comparison on WebDAV/FTPS password login | rustfs/rustfs#4403 | assert_ftps_ghsa_3p3x_wrong_credentials_rejected (crates/e2e_test/src/protocols/ftps_core.rs); GHSA-3p3x auth-failure block in test_webdav_core_operations (crates/e2e_test/src/protocols/webdav_core.rs) |
e2e (protocols suite) |
| GHSA-r5qv-rc46-hv8q | Internode RPC authentication must fail closed | rustfs/rustfs#4402 | ghsa_r5qv_resolve_shared_secret_rejects_default_fallback, ghsa_r5qv_verify_rpc_signature_fails_closed_on_missing_or_invalid_auth (crates/ecstore/src/cluster/rpc/http_auth.rs) |
unit |
| GHSA-m77q-r63m-pj89 | STS JWTs signed with shared root secret (intentionally unfixed) | n/a | test_created_sts_credentials_authorize_with_session_token_claims (crates/iam/src/sys.rs) — pins current behavior; sec-7 adds GHSA naming |
unit |
Where these run
-
Unit tests (
ghsa_r5qv_*incrates/ecstore) run automatically in the default CI pass viacargo nextest run/cargo test— no special wiring. -
Protocol e2e tests (WebDAV/FTPS constant-time login rejection) live in the
e2e_testprotocols suite, which binds fixed ports and requires--test-threads=1. Because of the fixed ports they cannot join thee2e-smokenextest profile (parallel, dynamic ports). They run manually today:RUSTFS_BUILD_FEATURES=ftps,webdav cargo test --package e2e_test \ test_protocol_core_suite -- --test-threads=1 --nocaptureWiring the security e2e lane into CI is tracked separately (sec-5, backlog#1151).
Adding a new advisory guard
- Reproduce the advisory's bypass form as a focused negative test.
- Name the test (or the helper/assertion)
ghsa_<id>_*, or attach aGHSA-<id>doc comment with the advisory URL and fix PR. - Add a row to the table above.
- Land the unit-level guard where the default CI pass runs it; land any e2e guard in the protocols suite (and register it with sec-5's filterset seam).