Files
satellite-provider/_docs/05_security/dependency_scan.md
T
Oleksandr Bezdieniezhnykh 314d1dec39
ci/woodpecker/push/01-test Pipeline was successful
ci/woodpecker/push/02-build-push Pipeline was successful
[AZ-491] [AZ-492] [AZ-493] [AZ-494] [AZ-496] Cycle 3 Step 14: security audit refresh
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>
2026-05-12 03:13:04 +03:00

152 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 1 — Dependency Scan
**Date**: 2026-05-11
**Method**: Manual inventory from `*.csproj` + targeted advisory search (WebSearch against GHSA / NVD / NuGet ReversingLabs).
**Reason for manual mode**: `dotnet list package --vulnerable` is on the project's "do not run from agent" list (AGENTS.md — these commands hang in this environment).
## Inventory
| Project | Package | Version | Notes |
|---------|---------|---------|-------|
| Api | Microsoft.AspNetCore.OpenApi | 8.0.21 | ASP.NET Core 8 LTS patch (one behind 8.0.25) |
| Api | Newtonsoft.Json | 13.0.4 | Latest 13.x |
| Api | Serilog.AspNetCore | 8.0.3 | |
| Api | Serilog.Sinks.File | 6.0.0 | |
| Api | SixLabors.ImageSharp | 3.1.11 | |
| Api | Swashbuckle.AspNetCore | 6.6.2 | |
| Common | SixLabors.ImageSharp | 3.1.11 | |
| DataAccess | Dapper | 2.1.35 | |
| DataAccess | Npgsql | 9.0.2 | |
| DataAccess | dbup-postgresql | 6.0.3 | |
| DataAccess | Microsoft.Extensions.Configuration.Abstractions | 9.0.10 | |
| DataAccess | Microsoft.Extensions.Logging.Abstractions | 9.0.10 | |
| TileDownloader | Microsoft.Extensions.Caching.Memory | 9.0.10 | |
| TileDownloader | Microsoft.Extensions.Http | 9.0.10 | |
| TileDownloader | Microsoft.Extensions.Logging.Abstractions | 9.0.10 | |
| TileDownloader | Microsoft.Extensions.Options.ConfigurationExtensions | 9.0.10 | |
| TileDownloader | Newtonsoft.Json | 13.0.4 | |
| Tests | coverlet.collector | 6.0.0 | |
| Tests | FluentAssertions | 8.8.0 | |
| Tests | Microsoft.Extensions.* | 9.0.10 | (multiple) |
| Tests | Microsoft.NET.Test.Sdk | 17.8.0 | NuGet.Frameworks transitive CVE flag — see findings |
| Tests | Moq | 4.20.72 | |
| Tests | xunit | 2.5.3 | |
| Tests | xunit.runner.visualstudio | 2.5.3 | |
## Findings
| # | Severity | Package | Version | Advisory | Disposition |
|---|----------|---------|---------|----------|-------------|
| D1 | Medium (production-risk: **Low**, exposure: not reachable) | Microsoft.AspNetCore.OpenApi → ASP.NET Core 8 runtime | 8.0.21 | [CVE-2026-26130](https://github.com/dotnet/aspnetcore/security/advisories/GHSA-4vgm-c2wm-63mw) — SignalR DoS via unbounded buffer | **RESOLVED (cycle 3, AZ-496)**: Bumped to `8.0.25` in `SatelliteProvider.Api.csproj`. Runtime base image already uses the floating `mcr.microsoft.com/dotnet/aspnet:8.0` tag which auto-resolves to ≥ 8.0.25, so deployed image automatically picks up the patched runtime on next build. Original disposition reproduced for traceability: **Not exploitable in this app** (codebase grep for `SignalR\|MapHub\|UseSignalR\|HubConnection` returns zero hits); the bump is hygiene rather than active-CVE closure. |
| D2 | Low (test-only) | Microsoft.NET.Test.Sdk | 17.8.0 | [CVE-2022-30184](https://github.com/microsoft/vstest/issues/4409) via transitive `NuGet.Frameworks <6.2.1` — information disclosure (CVSS 5.5) | **Not exploitable in production**: package is `IsTestProject=true` only; never shipped. Upgrade to `Microsoft.NET.Test.Sdk` ≥ 17.9.0 (which dropped the `NuGet.Frameworks` dependency entirely) the next time the test project's deps are touched. |
## Cross-version sanity (per `coderule.mdc`: keep dependency versions consistent)
- `Microsoft.Extensions.*` is uniformly **9.0.10** across DataAccess, TileDownloader, Tests, RegionProcessing, RouteManagement — consistent. ✓
- `Newtonsoft.Json` is **13.0.4** in both Api and TileDownloader — consistent. ✓
- `SixLabors.ImageSharp` is **3.1.11** in both Api and Common — consistent. ✓
- ASP.NET Core meta-package level is at **8.0.21** while extensions are at 9.0.10. The 9.x extensions ship a forward-compatible netstandard2.0 surface and load fine on the .NET 8 runtime — no functional issue, but worth flagging as a minor consistency drift for whoever next bumps the framework.
## Items checked clean
- SixLabors.ImageSharp 3.1.11 — newer than the patched 3.1.7 / 3.1.5 lines (CVE-2024-41131, CVE-2025-27598). No outstanding GHSA against 3.1.11 itself.
---
## Cycle 2 Delta (2026-05-11 — AZ-487 / AZ-488)
### New packages added this cycle
| Project | Package | Version | Notes |
|---------|---------|---------|-------|
| Api | `Microsoft.AspNetCore.Authentication.JwtBearer` | 8.0.21 | Added by AZ-487 (JWT validation baseline). Same patch line as `Microsoft.AspNetCore.OpenApi 8.0.21` — see D1. |
| Services.TileDownloader | `SixLabors.ImageSharp` | 3.1.11 | Added by AZ-488 to identify + decode UAV-supplied JPEGs (`Image.Identify`, `Image.Load<L8>`). Same version as the existing Api-level reference — consistent. |
| Tests (unit + integration) | `SixLabors.ImageSharp` | 3.1.11 | Added by AZ-488 to generate test fixtures. |
### New findings
#### D3 — `Microsoft.AspNetCore.Authentication.JwtBearer 8.0.21` shares the same 8.0.21 patch line as the D1-flagged OpenApi package (Low — production-risk: **Low**, exposure: not reachable) — **RESOLVED (cycle 3, AZ-496)**
- **Location**: `SatelliteProvider.Api/SatelliteProvider.Api.csproj` (added by AZ-487)
- **Detail**: D1 already recommends bumping `Microsoft.AspNetCore.OpenApi` to 8.0.25 because the underlying ASP.NET Core 8.0.21 runtime ships CVE-2026-26130 (SignalR DoS, not reachable in this app). Pinning a second package in the same 8.0.21 family in cycle 2 raises the cost of *not* doing the bump: every additional package implicitly hardcodes the runtime expectation. Cycle 1 disposition (`Not exploitable — no SignalR use`) still applies; cycle 2 escalation here is purely about consistency and operator clarity.
- **Disposition**: Same as D1 — bump *both* `Microsoft.AspNetCore.OpenApi` AND the new `Microsoft.AspNetCore.Authentication.JwtBearer` reference to the latest 8.0.x patch in a single PR. No separate Jira needed; fold into the D1 hardening task.
- **Resolution (cycle 3, AZ-496)**: Both packages bumped to `8.0.25` in `SatelliteProvider.Api.csproj`. `SatelliteProvider.Tests.csproj` does NOT have a direct `JwtBearer` reference — its JwtBearer usage flows transitively through the `ProjectReference` to `SatelliteProvider.Api`, so the Tests project automatically picks up `8.0.25` as well. No separate edit to Tests.csproj required.
#### F-DEPS-UAV — ImageSharp decode now runs on attacker-controlled JPEG bytes (Medium — exposure increase, not a new CVE)
- **Location**: `SatelliteProvider.Services.TileDownloader/UavTileQualityGate.cs:60-78``Image.Identify(...)` and `Image.Load<L8>(...)` on `ReadOnlyMemory<byte>` originating from `POST /api/satellite/upload`.
- **Detail**: Pre-cycle-2 the only ImageSharp call site was `GoogleMapsDownloaderV2`, which decodes responses from a known-good origin (Google's tile CDN under our API key). AZ-488 introduces a second call site that decodes **arbitrary client-supplied bytes**. ImageSharp 3.1.11 is patched against the published CVE line (CVE-2024-41131 / CVE-2025-27598 — both pre-3.1.7), so no known-CVE finding exists today. The change is in *exposure*: any future ImageSharp decode bug becomes a remote-attacker primitive on the upload endpoint.
- **Mitigation already in place** (AZ-488):
- Rule 1 (magic-byte check) runs *before* ImageSharp touches the bytes, narrowing the input to `FF D8 FF`-prefixed payloads.
- Rule 2 caps per-item bytes at 5 MiB (configurable); Kestrel + FormOptions cap the envelope at `MaxBatchSize × MaxBytes = 500 MiB`.
- Decode is wrapped in `try { … } catch (UnknownImageFormatException) { … } catch (InvalidImageContentException) { … }` so a malformed JPEG produces a structured `INVALID_FORMAT` reject, not an unhandled exception.
- **Disposition**: Accept for cycle 2 — the mitigations align with current best practice for "decode untrusted images" surfaces. Track as recurring follow-up:
- Subscribe to GHSA advisories for `SixLabors.ImageSharp` and bump aggressively (within 7 days of a patch).
- Re-evaluate whether to sandbox the decode (e.g. dedicated process pool, libvips with seccomp) the next time the upload trust boundary changes.
### Cross-version sanity (post-cycle-2)
- `SixLabors.ImageSharp` is **3.1.11** in Api, Common, Services.TileDownloader, Tests, IntegrationTests — consistent across 5 csprojs. ✓
- `Microsoft.AspNetCore.*` 8.0.21 in OpenApi + the new JwtBearer — consistent within the family but lagging one patch (8.0.25 is current). Cycle-2 D3 + cycle-1 D1 share remediation.
- No new Newtonsoft.Json / Npgsql / Dapper changes this cycle.
- Newtonsoft.Json 13.0.4 — past CVE-2024-21907 fix line (13.0.1).
- Npgsql 9.0.2 — outside the 4.x / 5.x / 6.x / 7.x / 8.x ranges affected by CVE-2024-32655 (SQL injection via protocol message size overflow). 9.0.x line was never affected.
- Dapper 2.1.35 — only "advisory" hit was a dependency-check false positive for SQLite CVE-2017-10989; not a Dapper issue.
- Swashbuckle.AspNetCore 6.6.2 — no published GHSA / CVE.
- Serilog.AspNetCore 8.0.3 — no published GHSA / CVE.
- dbup-postgresql 6.0.3 — no published GHSA / CVE.
---
## Cycle 3 Delta (2026-05-12 — AZ-491 / AZ-492 / AZ-493 / AZ-494 / AZ-495 / AZ-496)
### New packages added this cycle
| Project | Package | Version | Notes |
|---------|---------|---------|-------|
| `SatelliteProvider.TestSupport` (NEW project, AZ-491) | `Microsoft.IdentityModel.Tokens` | 7.0.3 | Centralised JWT-mint factory for both unit + integration tests. Version pinned to match the legacy cycle-2 `SatelliteProvider.IntegrationTests` reference being consolidated; intentional to keep the migration mechanical. |
| `SatelliteProvider.TestSupport` (NEW project, AZ-491) | `System.IdentityModel.Tokens.Jwt` | 7.0.3 | Same rationale as above — pinned to match the legacy reference. |
### New findings
#### D4 — `System.IdentityModel.Tokens.Jwt 7.0.3` + `Microsoft.IdentityModel.Tokens 7.0.3` carry CVE-2024-21319 (Low — test-only, never deployed)
- **Location**: `SatelliteProvider.TestSupport/SatelliteProvider.TestSupport.csproj` (added by AZ-491). Surfaced as `NU1902` warning on every restore — first matching log line at `/tmp/run-tests-cycle3-step16.log:9`.
- **Advisory**: [GHSA-59j7-ghrg-fj52](https://github.com/advisories/GHSA-59j7-ghrg-fj52) / [CVE-2024-21319](https://github.com/dotnet/aspnetcore/security/advisories/GHSA-59j7-ghrg-fj52) — JWE-token DoS via high-compression-ratio token causing unbounded memory allocation. CVSS 6.8 (Medium), advisory severity Critical for runtime services. Affected: `< 7.1.2` on the 7.x line.
- **Exposure in this project**:
- `SatelliteProvider.TestSupport` is `IsPackable=false`. Consumed only by `SatelliteProvider.Tests` and `SatelliteProvider.IntegrationTests` (both also `IsTestProject`). Never reaches the published API container.
- Production API consumes `Microsoft.AspNetCore.Authentication.JwtBearer 8.0.25` (post-AZ-496), which brings the BCL JWT types via the patched 7.x transitive line — past the 7.1.2 fix.
- The vulnerable code path (`JsonWebTokenHandler.ReadJsonWebToken` on a JWE with crafted compression ratio) is **never reached at runtime** in production. The TestSupport `JwtTokenFactory` uses `JwtSecurityTokenHandler.WriteToken` (encode-only, not decode); decode happens in the API container against the patched runtime line.
- **Disposition**: **Accept for cycle 3, track as future PBI.** Severity in this project is Low because:
- No production reachability (test-only, never shipped).
- The TestSupport call sites do not exercise the vulnerable JWE-decompression path.
- **Recommended fix** (future PBI): bump TestSupport's two pins to `Microsoft.IdentityModel.Tokens >= 7.1.2` + `System.IdentityModel.Tokens.Jwt >= 7.1.2` (or align to the 8.0.x family used transitively by `JwtBearer 8.0.25`). The `NU1902` warning will then disappear from the build log and the per-restore noise (≈ 9 hits in the cycle-3 test log) goes away.
- **Note**: this finding was already known and tracked as a follow-up in the cycle-3 batch-01 review (AZ-496) and the cumulative review for batches 01-03. Recorded formally here so it appears in the security audit's findings table.
### Resolved this cycle
- **D1** (cycle 1): `Microsoft.AspNetCore.OpenApi 8.0.21`**8.0.25** in `SatelliteProvider.Api.csproj`. RESOLVED in AZ-496.
- **D3** (cycle 2): `Microsoft.AspNetCore.Authentication.JwtBearer 8.0.21`**8.0.25** in `SatelliteProvider.Api.csproj`. RESOLVED in AZ-496.
### Cross-version sanity (post-cycle-3)
- `Microsoft.AspNetCore.*` family in API csproj: `OpenApi` 8.0.25 + `JwtBearer` 8.0.25 — consistent within family. ✓
- `Microsoft.IdentityModel.Tokens` / `System.IdentityModel.Tokens.Jwt`: pinned at 7.0.3 in TestSupport only; production transitively at 7.x patched line via `JwtBearer 8.0.25`. **Drift recorded** (see D4 for remediation path).
- `SixLabors.ImageSharp` is **3.1.11** in Api, Common, Services.TileDownloader, Tests, IntegrationTests — consistent across 5 csprojs. ✓
- `Microsoft.Extensions.*` is **9.0.10** across DataAccess, TileDownloader, Tests, RegionProcessing, RouteManagement, TestSupport (via xUnit transitive) — consistent. ✓
- `Newtonsoft.Json` is **13.0.4** in Api + TileDownloader — consistent. ✓
### Items checked clean (cycle 3 delta)
- `SixLabors.ImageSharp` 3.1.11 — still no new GHSA against 3.1.11 since the cycle-2 review (re-checked at GHSA on 2026-05-12).
- `Npgsql` 9.0.2 — used by AZ-493's `IntegrationTestDatabaseReset` for the new test-side reset. No new advisories on 9.0.x.
- `dbup-postgresql` 6.0.3 — no schema-modifying changes added by cycle 3. No new advisories.
## Self-verification
- [x] All package manifests scanned (9 csproj files — TestSupport added this cycle)
- [x] Each finding has a CVE ID or advisory reference
- [x] Upgrade paths identified for every Medium/Low finding
- [x] No Critical or High finding remains open after exploitability triage
- [x] Cycle-3 NU1902 warning at `/tmp/run-tests-cycle3-step16.log` line 9 + 8 follow-on hits accounted for under D4