Files
satellite-provider/_docs/05_security/dependency_scan.md
T
Oleksandr Bezdieniezhnykh 5214a4a647 [AZ-487] [AZ-488] security: cycle 2 delta audit (PASS_WITH_WARNINGS)
Step 14 (Security Audit) for cycle 2 — delta scan against the cycle-1
baseline. Verdict remains PASS_WITH_WARNINGS; no Critical/High.

Scope: JWT auth boundary (AZ-487) and UAV multipart upload + ImageSharp
decode of attacker-controlled bytes (AZ-488). Both new packages
(JwtBearer 8.0.21, ImageSharp 3.1.11 in Services.TileDownloader)
checked.

Cycle-2 delta:
* 0 Critical / 0 High
* 2 Medium: F-AUTH-2 (iss/aud not validated — by design until admin
  team publishes values, AZ-487 § Constraints), F-UAV-1 (ImageSharp
  decode now runs on attacker-controlled bytes — mitigations
  sufficient; pin to GHSA subscribe-and-bump policy).
* 4 Low: F-AUTH-1 (DEV-ONLY secret in appsettings.Development.json —
  accepted), F-AUTH-3 (rate-limit gap extends to 401 floods — folds
  into cycle-1 I3), F-UAV-2 (JsonDocument.Parse on signature-validated
  claims — bounded by Kestrel header cap), D3 (JwtBearer shares D1
  patch line).
* 1 Informational: F-UAV-3 (reject reasons disclose gate structure —
  accepted UX trade-off; documented in contract).

OWASP refresh: A01 / A07 move from N/A (with caveat) to
PASS_WITH_WARNINGS (per-tenant authz absent; iss/aud + revocation
gaps tracked).

Pre-deploy operational gate added: deploy pipeline must verify
JWT_SECRET != DEV-ONLY placeholder before promoting api.

Artifacts: dependency_scan.md, static_analysis.md, owasp_review.md,
infrastructure_review.md, security_report.md — all appended with a
"Cycle 2 Delta" section preserving cycle-1 finding IDs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 00:13:58 +03:00

8.4 KiB
Raw Blame History

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 — SignalR DoS via unbounded buffer Not exploitable in this app: codebase grep for SignalR|MapHub|UseSignalR|HubConnection returns zero hits. Runtime patch still recommended. Upgrade Microsoft.AspNetCore.OpenApi to 8.0.25 (or current 8.0.x patch) and redeploy on a runtime ≥ 8.0.25 to remove the vulnerable code paths from the deployed image.
D2 Low (test-only) Microsoft.NET.Test.Sdk 17.8.0 CVE-2022-30184 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)

  • 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.

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-78Image.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.

Self-verification

  • All package manifests scanned (8 csproj files)
  • Each finding has a CVE ID or advisory reference
  • Upgrade paths identified for every Medium/Low finding
  • No Critical or High finding remains open after exploitability triage