# 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
