mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 16:28:15 +00:00
test(security): wire negative-auth suites into e2e-smoke with a count-floor guard (#4815)
The header-SigV4 (sec-1), presigned-URL (sec-2), and admin-gate (sec-4) negative auth-rejection e2e suites merged earlier but only presigned_negative was actually selected by any CI profile; negative_sigv4_test and admin_auth_test compiled and sat unrun. Add both to the e2e-smoke default-filter so all three attacker-facing S3 auth-rejection suites execute on every PR. They already meet the smoke admission criteria (RustFSTestEnvironment, random ports, parallel-safe, no #[ignore], no feature gates), so this is a pure filterset change — the single e2e-in-CI wiring mechanism (backlog#1149 ci-4), not a new job. Because the filter selects by module name, a rename or deletion could silently drop a suite out of the security gate with no CI signal. Add scripts/check_security_smoke_count.sh (infra-12 count-floor mechanism): it lists what the e2e-smoke profile selects and fails if the count of security auth-rejection tests drops below the committed floor in .config/security-smoke-floor.txt (16). Invoked from the e2e-tests job, before the smoke run, so the nextest list compiles the binaries the run reuses. The GHSA-3p3x FTPS/WebDAV constant-time e2e (protocols::test_protocol_core_suite) stays out by topology: it binds fixed ports, needs the ftps,webdav features, and is #[serial], so it cannot join the random-port default-feature smoke profile as a filterset change (global ruling G5). Its GHSA-r5qv sibling is a unit test that already runs in the default CI pass. docs/testing/security-regressions.md now carries the full CI-execution map and flags the GHSA-3p3x e2e CI-lane gap as a ci-domain follow-up. Refs: backlog#1151 (sec-5)
This commit is contained in:
@@ -22,21 +22,45 @@ forced to update its pinned test (red -> green).
|
||||
| [GHSA-r5qv-rc46-hv8q](https://github.com/rustfs/rustfs/security/advisories/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](https://github.com/rustfs/rustfs/security/advisories/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
|
||||
## Where these run (CI-execution map)
|
||||
|
||||
- **Unit tests** (`ghsa_r5qv_*` in `crates/ecstore`) run automatically in the
|
||||
default CI pass via `cargo nextest run` / `cargo test` — no special wiring.
|
||||
- **Protocol e2e tests** (WebDAV/FTPS constant-time login rejection) live in the
|
||||
`e2e_test` protocols suite, which binds **fixed ports** and requires
|
||||
`--test-threads=1`. Because of the fixed ports they **cannot** join the
|
||||
`e2e-smoke` nextest profile (parallel, dynamic ports). They run manually today:
|
||||
Every security regression must land where CI actually runs it — a named test in
|
||||
an unexecuted suite is theater. The suites split across three execution paths by
|
||||
topology:
|
||||
|
||||
- **Unit tests** — `ghsa_r5qv_*` (`crates/ecstore`) and the GHSA-m77q STS
|
||||
pinning (`crates/iam`) run automatically in the default CI pass
|
||||
(`cargo nextest run --profile ci --all --exclude e2e_test`) — no special
|
||||
wiring. This is the CI-executed regression for the RPC fail-closed (r5qv) and
|
||||
STS-signing (m77q) advisories.
|
||||
- **S3-API negative-auth e2e (e2e-smoke, PR-gated)** — the attacker-facing S3
|
||||
auth-rejection suites run on every PR via the `e2e-smoke` nextest profile
|
||||
(`.config/nextest.toml`), which each spawns its own server on a random port
|
||||
and is parallel-safe:
|
||||
- `negative_sigv4_test` — tampered/wrong-key/skewed header SigV4 (sec-1)
|
||||
- `presigned_negative_test` — expired/tampered/wrong-key presigned URLs (sec-2)
|
||||
- `admin_auth_test` — non-admin denial + root-credential lifecycle (sec-4)
|
||||
|
||||
A count-floor guard (`scripts/check_security_smoke_count.sh`, floor in
|
||||
`.config/security-smoke-floor.txt`) runs in the `e2e-tests` CI job and fails if
|
||||
a rename drops any of these out of the smoke filter (infra-12 mechanism). This
|
||||
is the sec-5 wiring: those merged suites were dead weight until listed here.
|
||||
- **Protocol e2e (WebDAV/FTPS constant-time login, GHSA-3p3x)** — lives in the
|
||||
`e2e_test` protocols suite (`test_protocol_core_suite`), which binds **fixed
|
||||
ports**, needs the `ftps,webdav` build features, and is `#[serial]`. Those
|
||||
three properties make it **structurally incompatible** with the random-port,
|
||||
default-feature, parallel `e2e-smoke` profile: it cannot be a filterset change,
|
||||
so sec-5 (scoped to a filterset change, global ruling G5) does not wire it.
|
||||
It runs manually today:
|
||||
|
||||
```bash
|
||||
RUSTFS_BUILD_FEATURES=ftps,webdav cargo test --package e2e_test \
|
||||
test_protocol_core_suite -- --test-threads=1 --nocapture
|
||||
```
|
||||
|
||||
Wiring the security e2e lane into CI is tracked separately (sec-5, backlog#1151).
|
||||
**Open gap:** GHSA-3p3x's *e2e* layer has no PR-gated CI execution. A protocols
|
||||
e2e CI lane is a ci-domain concern (a new profile/job, not a filterset change);
|
||||
it is deliberately out of sec-5's boundary and left as a follow-up.
|
||||
|
||||
## Adding a new advisory guard
|
||||
|
||||
@@ -44,5 +68,8 @@ forced to update its pinned test (red -> green).
|
||||
2. Name the test (or the helper/assertion) `ghsa_<id>_*`, or attach a
|
||||
`GHSA-<id>` doc comment with the advisory URL and fix PR.
|
||||
3. Add a row to the table above.
|
||||
4. 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).
|
||||
4. Land it where CI runs it (see the map above): a unit guard in the default CI
|
||||
pass; an S3-API negative-auth e2e in the `e2e-smoke` filter (add the module to
|
||||
`.config/nextest.toml` and bump `.config/security-smoke-floor.txt`); a
|
||||
fixed-port protocol e2e in the protocols suite (still manual — see the open
|
||||
gap above).
|
||||
|
||||
Reference in New Issue
Block a user