# Static Analysis (Cycle 10)

**Date**: 2026-06-25
**Mode**: Delta scan
**Scope**: AZ-1113 REST 400 error message sanitization. Cycle-9 baseline remains authoritative for gRPC surface.

**Files in scope**:
- `SatelliteProvider.Api/GlobalExceptionHandler.cs`
- `SatelliteProvider.Api/Validators/UavUploadValidationFilter.cs`
- `SatelliteProvider.Services.TileDownloader/UavTileUploadHandler.cs`
- `SatelliteProvider.Tests/GlobalExceptionHandlerTests.cs`
- `SatelliteProvider.Tests/UavTileUploadHandlerTests.cs`
- `SatelliteProvider.IntegrationTests/UavUploadValidationTests.cs` (+ tightened assertions in region/route/inventory validation tests)

**Method**: Read changed call sites; verify static constants replace `ex.Message` / `badRequest.Message` echoes; grep for remaining raw exception text in client-facing 400 paths.

## Resolved findings (AZ-1113)

### F-AZ795-1 — `JsonException.Message` propagated in `GlobalExceptionHandler` (Low / A09) — **RESOLVED**

- **Location**: `GlobalExceptionHandler.cs` (deserializer branch).
- **Resolution**: `errors[<path>]` values use `JsonFieldErrorMessage` (`"The field value is invalid."`). Unit test `TryHandleAsync_DeserializationFailure_WritesValidationProblemDetailsWithJsonPath_AZ795` asserts no `TileInventoryRequest` type name leak.

### F-AZ795-2 — `BadHttpRequestException.Message` propagated as `detail` (Low / A09) — **RESOLVED**

- **Location**: `GlobalExceptionHandler.cs` (non-JSON bind branch).
- **Resolution**: `detail` uses `BadRequestDetailMessage` (`"The request could not be processed."`). Unit test `TryHandleAsync_BadHttpRequestExceptionWithoutJson_UsesStaticDetail` asserts no `Latitude` echo.

### F-AZ810-1 — `JsonException.Message` in `UavUploadValidationFilter` (Low / A09) — **RESOLVED**

- **Location**: `UavUploadValidationFilter.cs`.
- **Resolution**: `errors["metadata"]` uses `MetadataJsonParseError` (`` `metadata` could not be parsed as JSON. ``). Integration test `MetadataNotAnObject_Returns400` asserts response body lacks `System.`.

### F-AZ810-1b — Defence-in-depth path in `UavTileUploadHandler` (Low / A09) — **RESOLVED**

- **Location**: `UavTileUploadHandler.cs` metadata parse catch.
- **Resolution**: Envelope error uses same static string as filter. Unit test `HandleAsync_InvalidMetadataJson_ReturnsEnvelopeError`.

## Open carry-overs (unchanged by cycle 10)

### F-AZ810-2 — `UavTileMetadata.CapturedAt` typed `DateTime` not `DateTimeOffset` (Low / Informational)

- Still open — separate task per AZ-1113 exclusions.

## Pass areas (cycle-10 delta)

| Area | Result |
|------|--------|
| SQL injection | N/A — no SQL changes |
| Hardcoded secrets | None introduced |
| 5xx sanitization (AZ-353) | Unchanged — still sanitised |
| gRPC error messages | Unchanged from cycle-9 fix — still generic |
| New attack surface | None — message content only |

## Verdict

**PASS** (cycle-10 delta) — three REST information-disclosure carry-overs resolved; zero new findings.
