[AZ-491] [AZ-492] [AZ-493] [AZ-494] [AZ-496] Cycle 3 Step 14: security audit refresh
ci/woodpecker/push/01-test Pipeline was successful
ci/woodpecker/push/02-build-push Pipeline was successful

All 5 phases refreshed against cycle-3 delta:

Phase 1 (Dependency Scan):
  - D1 RESOLVED (AZ-496): Microsoft.AspNetCore.OpenApi 8.0.21 → 8.0.25
  - D3 RESOLVED (AZ-496): JwtBearer 8.0.21 → 8.0.25
  - D4 NEW (Low, test-only): System.IdentityModel.Tokens.Jwt 7.0.3 +
    Microsoft.IdentityModel.Tokens 7.0.3 pinned in TestSupport carry
    CVE-2024-21319 (JWE DoS). Bump to ≥ 7.1.2 tracked as future PBI.

Phase 2 (Static Analysis):
  - F-AUTH-3 (Info): test runner Program.cs logs iss/aud at startup;
    production API does NOT (verified by grep).
  - F-AUTH-4 (Info): DEV-ONLY iss/aud placeholders in
    appsettings.Development.json + .env.example — by design per
    Option B for AZ-494.
  - F-DBR-1: TRUNCATE string interpolation in
    IntegrationTestDatabaseReset.cs — false positive (hard-coded
    table list).
  - F-DBR-2 (Low): TRUNCATE guard is operator-bypassable. Two-guard
    model is conservative-by-default and unit-tested.
  - F-PERF-1 (Low): perf-bootstrap --mint-only writes a 4-hour
    GPS-permission token to stdout. Operator-trusted machine assumed.

Phase 3 (OWASP Top 10):
  - A03 carries D1/D3 RESOLVED + D4 NEW.
  - A07 flips F-AUTH-2 to RESOLVED (AZ-494); residual revocation-list
    Low recorded.
  - A05 status unchanged (F-DBR-1 false positive).
  - A08 picks up F-DBR-2.

Phase 4 (Infrastructure):
  - JWT_ISSUER / JWT_AUDIENCE flow .env → compose → Kestrel config,
    same pattern as JWT_SECRET.
  - INTEGRATION_TEST_DB_RESET + ASPNETCORE_ENVIRONMENT=Testing wired
    for AZ-493 reset gate.
  - SatelliteProvider.TestSupport is IsPackable=false — never ships
    in a production container image.
  - New operational gate added to deploy runbook: grep for DEV-ONLY-
    in the rendered deploy environment must return zero hits.

Phase 5 (Security Report):
  - Verdict: PASS_WITH_WARNINGS (cycle 3 does not escalate).
  - 0 Critical, 0 High, 0 new Medium.
  - Cycle-2 F-AUTH-2 (Medium) RESOLVED; cycle-1 D1 + cycle-2 D3
    RESOLVED.

Autodev state advanced to Step 14 completed. Next: Step 15
(Performance Test, optional gate).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-12 03:13:04 +03:00
parent e42bf62152
commit 314d1dec39
6 changed files with 248 additions and 8 deletions
+35
View File
@@ -71,3 +71,38 @@ Cycle 1's A01 / A07 verdicts were `N/A (with caveat)` because the service shippe
| A07 | F-AUTH-2 — `iss`/`aud` not validated | Medium → **Resolved cycle 3 (AZ-494)** | n/a |
| A07 | No token revocation list (residual after AZ-494) | Low | Phase 2 — out of scope until requirement emerges |
| (claim handler) | F-UAV-2 — `JsonDocument.Parse` on token claim values | Low | Phase 2 |
---
## Cycle 3 Refresh (AZ-491 / AZ-492 / AZ-493 / AZ-494 / AZ-495 / AZ-496)
Cycle 3 was test-infrastructure + dependency + iss/aud-validation work. Most production surfaces are untouched; the OWASP impact is concentrated on A03 (supply chain) and A07 (auth). A02 also picks up one Informational note about the DEV-ONLY iss/aud handling pattern.
| # | Category | Cycle 2 Status | Cycle 3 Status | Cycle-3 evidence |
|---|----------|----------------|----------------|------------------|
| A01 | Broken Access Control | PASS_WITH_WARNINGS | **PASS_WITH_WARNINGS** (unchanged) | No endpoint added or relaxed. AZ-494 strictly tightens token acceptance (wrong iss/aud → 401). |
| A02 | Security Misconfiguration | FAIL (S1, S2, I1, I2, F-AUTH-1) | **FAIL** (unchanged + F-AUTH-4) | F-AUTH-4: DEV-ONLY iss/aud placeholders committed to `appsettings.Development.json` + `.env.example` (Informational, by-design per Option B; mirrors the F-AUTH-1 pattern for `JWT_SECRET`). Underlying cycle-1 findings (Postgres default creds, root container, no security headers) untouched. |
| A03 | Supply Chain Failures | PASS_WITH_WARNINGS (D1, D2, D3, F-DEPS-UAV) | **PASS_WITH_WARNINGS** (D1 + D3 RESOLVED; + D4) | **D1 RESOLVED** (cycle 3, AZ-496) — `Microsoft.AspNetCore.OpenApi` 8.0.21 → 8.0.25. **D3 RESOLVED** (cycle 3, AZ-496) — `JwtBearer` 8.0.21 → 8.0.25. **D4 NEW**`System.IdentityModel.Tokens.Jwt 7.0.3` + `Microsoft.IdentityModel.Tokens 7.0.3` pinned in `SatelliteProvider.TestSupport` carry CVE-2024-21319 (JWE DoS) — Low, test-only never deployed. D2 and F-DEPS-UAV unchanged. |
| A04 | Cryptographic Failures | PASS | **PASS** | HS256 contract unchanged. AZ-494 added validation flags but not new crypto. |
| A05 | Injection | PASS | **PASS** | AZ-493's TRUNCATE uses a hard-coded table list (F-DBR-1 explicit false-positive in static_analysis.md). No new SQL / shell / template surfaces. |
| A06 | Insecure Design | FAIL (S3, S4, I3, F-AUTH-3, F-UAV-3) | **FAIL** (unchanged) | Rate limiting still absent. AZ-494 reduces the 401-flood vector slightly (more reasons to reject malformed tokens earlier) but the gap itself is unchanged. |
| A07 | Identification & Authentication Failures | PASS_WITH_WARNINGS (F-AUTH-2 open) | **PASS_WITH_WARNINGS** (F-AUTH-2 RESOLVED; revocation-list still residual) | F-AUTH-2 resolved by AZ-494: `ValidateIssuer = true` + `ValidateAudience = true` against env-sourced values with fail-fast contract. Verified by SEC-12 + SEC-13 integration scenarios + 4 unit fail-fast tests, all PASS at Step 11. F-AUTH-3 (test-runner iss/aud log line) Informational only. F-AUTH-4 (DEV-ONLY placeholders) by design. Residual: no token revocation list — Low, out of scope. |
| A08 | Software or Data Integrity Failures | PASS | **PASS** | No CI/CD changes; no new auto-update path. AZ-493's TRUNCATE is destructive but gated by two soft guards (F-DBR-2, Low). |
| A09 | Security Logging Failures | PASS_WITH_WARNINGS (I4) | **PASS_WITH_WARNINGS** (unchanged) | No new logging changes. Production API does NOT log iss/aud (verified by repo grep returning no hits in `Api/Program.cs`). |
| A10 | Mishandling of Exceptional Conditions | PASS | **PASS** | AZ-494's `ResolveRequiredOrThrow` throws `InvalidOperationException` at STARTUP, not at request time — no client-facing leakage. `GlobalExceptionHandler` invariant unchanged. |
### Cycle-3 cross-reference
| OWASP Cat | Cycle-3 finding | Severity | Source phase |
|-----------|-----------------|----------|--------------|
| A02 | F-AUTH-4 — DEV-ONLY iss/aud placeholders in dev config | Informational (by design) | Phase 2 |
| A03 | D1 — `Microsoft.AspNetCore.OpenApi` 8.0.21 → 8.0.25 | **RESOLVED (AZ-496)** | Phase 1 |
| A03 | D3 — `JwtBearer` 8.0.21 → 8.0.25 | **RESOLVED (AZ-496)** | Phase 1 |
| A03 | D4 — `System.IdentityModel.Tokens.Jwt 7.0.3` + `Microsoft.IdentityModel.Tokens 7.0.3` in TestSupport (CVE-2024-21319) | Low (test-only) | Phase 1 |
| A05 | F-DBR-1 — `TRUNCATE` string interpolation in `IntegrationTestDatabaseReset` | **False positive** (hard-coded table list) | Phase 2 |
| A07 | F-AUTH-2 — `iss` / `aud` not validated | **RESOLVED (AZ-494)** | n/a |
| A07 | F-AUTH-3 — test runner logs iss/aud at startup | Informational (test-only) | Phase 2 |
| A07 | F-AUTH-4 — DEV-ONLY placeholders (also A02-flagged) | Informational (by design) | Phase 2 |
| A07 | No token revocation list (residual after AZ-494) | Low (out of scope) | n/a |
| A08 | F-DBR-2 — TRUNCATE guard is operator-bypassable | Low (deliberate trade-off, unit-tested) | Phase 2 |
| A06 / A07 | F-PERF-1 — perf-bootstrap 4-hour `GPS` token written to stdout | Low (operator-controlled CLI) | Phase 2 |