Files
satellite-provider/_docs/05_security/static_analysis_cycle9.md
T
Oleksandr Bezdieniezhnykh 7ed780b063
ci/woodpecker/push/01-test Pipeline failed
ci/woodpecker/push/02-build-push unknown status
[AZ-1074] [AZ-1075] Cycle 9 closeout: security, tests, metrics
Resolve F-AZ1074-1/2 (collection caps, generic gRPC internal errors).
Standalone integration compose stack, docs, security audit, perf and retro.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-25 17:32:14 +03:00

3.2 KiB

Static Analysis (Cycle 9)

Date: 2026-06-25 Mode: Delta scan Scope: AZ-1074 + AZ-1075 gRPC surface. Cycle-8 baseline remains authoritative for REST validators.

Files in scope:

  • SatelliteProvider.Api/Grpc/RouteTileDeliveryGrpcService.cs (new)
  • SatelliteProvider.Api/Program.cs (AddGrpc, MapGrpcService, message size limits)
  • SatelliteProvider.Services.RouteManagement/TileProvision/RouteTileDeliveryOrchestrator.cs (validation hardening)
  • SatelliteProvider.GrpcContracts/tile_provision.proto + generated stubs
  • SatelliteProvider.IntegrationTests/RouteTileDeliveryGrpcTests.cs, GrpcTestHelpers.cs
  • SatelliteProvider.IntegrationTests/Dockerfile (linux/amd64, aspnet runtime)
  • docker-compose.tests.yml (self-contained test stack)

Method: End-to-end read of new files; grep for hardcoded secrets; trace auth middleware order; compare gRPC validation bounds vs REST CreateRouteRequestValidator.

Findings

F-AZ1074-1 — Unbounded gRPC request collections enable authenticated DoS (Medium / A04) — RESOLVED in cycle 9 (Step-14 follow-up)

  • Location: RouteTileDeliveryOrchestrator.ValidateJob (pre-fix).
  • Description: DeliverRouteTiles accepted unbounded waypoints, geofences, and client_tiles protobuf repeated fields. REST POST /api/satellite/route caps points at 500 and geofences.polygons at 50 (cycle-8 F-AZ809-1 fix); gRPC had no equivalent caps before cycle 9 Step 14.
  • Impact: Medium. Auth-gated ([Authorize] on RouteTileDeliveryGrpcService; JWT metadata required). Authenticated operator could force large CPU/memory work in RouteTileExpander.Expand and ClientTileCatalog.IndexByZxy.
  • Resolution: Added MaxWaypoints = 500, MaxGeofencePolygons = 50, MaxClientTiles = 5000 (inventory cap parity) to ValidateJob. Unit test DeliverAsync_TooManyWaypoints_Throws added.

F-AZ1074-2 — Internal exception message echoed to gRPC client (Low / A09) — RESOLVED in cycle 9 (Step-14 follow-up)

  • Location: RouteTileDeliveryGrpcService.cs:55-58 (pre-fix).
  • Description: Generic catch (Exception) wrote ex.Message into stream DeliveryError.Message — parallel to cycle-7 F-AZ795-1 (REST ProblemDetails path).
  • Impact: Low. Auth-gated. Could leak internal exception text to authenticated clients.
  • Resolution: Client message replaced with generic "An internal error occurred."; full exception still logged server-side.

Pass areas (cycle-9 delta)

Area Result
SQL injection N/A — no new raw SQL
Hardcoded secrets None in new files
gRPC auth [Authorize] + UseAuthentication/UseAuthorization before MapGrpcService
JWT on gRPC Integration tests pass Bearer token via metadata — matches REST contract
Message size limits MaxReceiveMessageSize = 16 MiB, MaxSendMessageSize = 64 MiB configured
Protobuf parsing Bounded by Kestrel/gRPC message limits; collection caps added post-audit
Test fixtures GrpcTestHelpers uses env-resolved JWT via JwtTestHelpers.MintAuthenticated — no embedded secrets

Verdict

PASS_WITH_WARNINGS at audit time (1 Medium open → resolved in Step-14 follow-up). Post-fix delta: PASS for cycle-9 new code.