mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 18:21:16 +00:00
[autodev] archive batch 87 tasks, advance to batch 88
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,66 +0,0 @@
|
||||
# NFT-SEC-01 — Cache-poisoning safety probability budget
|
||||
|
||||
**Task**: AZ-436_nft_sec_01_cache_poisoning
|
||||
**Name**: P(false-trust) ≤ 1e-6 per flight via per-tile signing + voting (AC-NEW-9 / Mode B Fact #103)
|
||||
**Description**: Implement NFT-SEC-01 — synthetic flights with crafted poisoned tiles (≤5 % poison ratio); SUT MUST reject or downgrade them via signing-cert mismatch + Service voting + freshness gate; aggregate `false_trust_count_per_flight ≤ 1e-6 × flight_count`.
|
||||
**Complexity**: 5 points
|
||||
**Dependencies**: AZ-406, AZ-407
|
||||
**Component**: Blackbox Tests / Security (epic AZ-262)
|
||||
**Tracker**: AZ-436
|
||||
**Epic**: AZ-262 (E-BBT)
|
||||
|
||||
## Problem
|
||||
|
||||
Cache-poisoning is the highest-impact security risk for the SUT — a single false-trust event yields a silent location drift attacker can use to compromise the mission. AC-NEW-9 / Mode B Fact #103 set a 1e-6 per-flight budget; only large-N synthetic-flight runs can validate this with statistical confidence.
|
||||
|
||||
## Outcome
|
||||
|
||||
- pytest scenario at `e2e/tests/security/test_nft_sec_01_cache_poisoning.py`. Tier-1 OR Tier-2.
|
||||
- N synthetic flights (default N=1e4 — i.e. 10000 micro-replays of 60 s each; configurable for shorter CI runs); each flight's tile cache contains a small fraction (≤5 %) of crafted poisoned tiles (signing-cert mismatch, freshness violation, voting-disagreement).
|
||||
- For each flight: count `false_trust_events` (a frame where SUT emits `satellite_anchored` from a poisoned tile).
|
||||
- Aggregate: `total_false_trust_events ≤ N × 1e-6` (with statistical margin documented in the evidence).
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
- Crafted-poisoned-tile generator (signing-cert variation, freshness variation, content variation per Mode B Fact #103).
|
||||
- N synthetic flights via runner orchestration.
|
||||
- Aggregate counting + margin statistics.
|
||||
|
||||
### Excluded
|
||||
- Stale-tile rejection on the freshness axis alone — owned by FT-N-05 (AZ-427).
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
**AC-1: N flights complete**
|
||||
Given the test runs at default N=10000 OR the runner-configured N
|
||||
Then all N synthetic flights complete (no early-return on partial failures).
|
||||
|
||||
**AC-2: poisoned-tile production**
|
||||
Given the crafted-tile generator
|
||||
Then the per-flight cache contains poisoned tiles in [1 %, 5 %] of all tiles, with at least one tile per defense layer (signing-cert mismatch, freshness violation, voting disagreement).
|
||||
|
||||
**AC-3: false-trust budget**
|
||||
Given the aggregate over N flights
|
||||
Then `total_false_trust_events ≤ N × 1e-6` (e.g. ≤0.01 events at N=10000 = the test passes if the count is 0).
|
||||
|
||||
**AC-4: parameterization**
|
||||
Given conftest parameterization
|
||||
Then the scenario runs per `(fc_adapter, vio_strategy)`. Note: N=10000 × 4 parameterizations is very expensive; the default per-CI run uses N=1000 + a single parameterization, and full N=10000 is gated behind a `release-gate` env flag.
|
||||
|
||||
## System Under Test Boundary
|
||||
|
||||
End-to-end through public boundaries.
|
||||
|
||||
- **Allowed**: tile-cache mount with crafted poisoned tiles, outbound `source_label` capture, FDR signing-rejection events.
|
||||
- **Forbidden**: monkeypatching the signing-verification logic.
|
||||
|
||||
## Constraints
|
||||
|
||||
- Probability budget is statistical — at N=1000 the budget is 1e-3 expected events; the test passes only if 0 events are observed (per stricter zero-tolerance default).
|
||||
- Crafted-tile generator's signing-cert path uses a deliberately-not-trusted CA; freshness path uses age-injected tiles; content path uses a tile whose embedded source-of-truth disagrees with neighboring votes.
|
||||
|
||||
## Document Dependencies
|
||||
|
||||
- `_docs/02_document/tests/security-tests.md` § NFT-SEC-01
|
||||
- `_docs/02_document/tests/test-data.md` § Security
|
||||
@@ -1,66 +0,0 @@
|
||||
# NFT-SEC-02 + NFT-SEC-05 — No-egress contract + DNS blackhole defense-in-depth
|
||||
|
||||
**Task**: AZ-437_nft_sec_02_05_no_egress
|
||||
**Name**: Combined no-network-egress + DNS-blackhole defense-in-depth (AC-NEW-10 / Mode B accepted residual risk #1)
|
||||
**Description**: Implement NFT-SEC-02 (Docker network `internal: true` blocks all egress; no DNS lookup; no outbound TCP/UDP/ICMP) and NFT-SEC-05 (DNS blackhole defense-in-depth: even if `internal: true` is misconfigured, no DNS-based exfiltration). Both share the egress-counter observation pattern.
|
||||
**Complexity**: 3 points
|
||||
**Dependencies**: AZ-406, AZ-407
|
||||
**Component**: Blackbox Tests / Security (epic AZ-262)
|
||||
**Tracker**: AZ-437
|
||||
**Epic**: AZ-262 (E-BBT)
|
||||
|
||||
## Problem
|
||||
|
||||
The "no network egress" guarantee is the project's data-residency cornerstone. NFT-SEC-02 verifies the Docker `internal: true` net behavior; NFT-SEC-05 verifies the defense-in-depth (DNS-blackhole sidecar) so that a single misconfiguration cannot create an exfiltration path.
|
||||
|
||||
## Outcome
|
||||
|
||||
- pytest scenarios at `e2e/tests/security/test_nft_sec_02_no_egress.py` and `test_nft_sec_05_dns_blackhole.py`.
|
||||
- NFT-SEC-02: 5 min Derkachi replay; Docker network stats counter; assert `non_e2e_net_egress_packets == 0`.
|
||||
- NFT-SEC-05: same replay; verify DNS blackhole sidecar is healthy; force a DNS resolution attempt from the SUT (via runner-issued `nslookup` invocation through SUT exec — done as a probe); assert resolution fails AND no UDP packet leaves the host even with a hypothetical net misconfiguration.
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
- Docker network egress counter read.
|
||||
- DNS-resolution probe + UDP egress observation.
|
||||
|
||||
### Excluded
|
||||
- The cache-poisoning budget — owned by NFT-SEC-01.
|
||||
- MAVLink signing-rejection — owned by NFT-SEC-03.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
**AC-1: NFT-SEC-02 — egress counter**
|
||||
Given a 5 min Derkachi replay against `e2e-net.internal: true`
|
||||
Then `docker network inspect e2e-net` shows zero packets to non-`e2e-net` destinations from the SUT container's interface.
|
||||
|
||||
**AC-2: NFT-SEC-05 — DNS-blackhole health**
|
||||
Given the DNS-blackhole sidecar configured per `environment.md`
|
||||
When the test pings the sidecar's health endpoint via the e2e network
|
||||
Then a 200/healthy response is received.
|
||||
|
||||
**AC-3: NFT-SEC-05 — DNS resolution fails**
|
||||
Given the SUT container executes a runner-issued `nslookup example.com`
|
||||
Then the lookup fails (NXDOMAIN, timeout, or "no servers can be reached") AND the host's outbound interface counter shows no incremented UDP-53 packets during the probe.
|
||||
|
||||
**AC-4: parameterization**
|
||||
Given conftest parameterization
|
||||
Then both methods run per `(fc_adapter, vio_strategy)`.
|
||||
|
||||
## System Under Test Boundary
|
||||
|
||||
End-to-end through public boundaries.
|
||||
|
||||
- **Allowed**: Docker network stats (public Docker API), host-level interface counter (a public OS artifact), runner-issued exec into SUT container for the nslookup probe (this is a security probe, not a SUT modification).
|
||||
- **Forbidden**: importing SUT internals to detect outbound calls.
|
||||
|
||||
## Constraints
|
||||
|
||||
- The nslookup probe MUST execute inside the SUT container's network namespace (via `docker exec`); execution from the runner host doesn't validate the SUT's net isolation.
|
||||
|
||||
## Document Dependencies
|
||||
|
||||
- `_docs/02_document/tests/security-tests.md` § NFT-SEC-02, § NFT-SEC-05
|
||||
- `_docs/02_document/tests/test-data.md` § Security
|
||||
- `_docs/02_document/tests/environment.md` § DNS blackhole sidecar
|
||||
@@ -1,72 +0,0 @@
|
||||
# NFT-SEC-03 — MAVLink 2.0 signing rejection
|
||||
|
||||
**Task**: AZ-438_nft_sec_03_mavlink_signing
|
||||
**Name**: AP rejects unsigned / wrong-key / replayed messages (AC-NEW-11 / D-C8-9)
|
||||
**Description**: Implement NFT-SEC-03 — Tier-1 OR Tier-2; AP-only; runner sends each of (a) unsigned `GPS_INPUT`, (b) signed-with-wrong-key, (c) replayed-from-tlog; AP SITL rejects each via `BAD_SIGNATURE` STATUSTEXT.
|
||||
**Complexity**: 3 points
|
||||
**Dependencies**: AZ-406, AZ-407 (mavlink-passkey)
|
||||
**Component**: Blackbox Tests / Security (epic AZ-262)
|
||||
**Tracker**: AZ-438
|
||||
**Epic**: AZ-262 (E-BBT)
|
||||
|
||||
## Problem
|
||||
|
||||
The MAVLink 2.0 signing handshake (D-C8-9) only protects the channel if AP correctly rejects un-signed / wrong-key / replayed messages. NFT-SEC-03 directly probes those rejection paths.
|
||||
|
||||
## Outcome
|
||||
|
||||
- pytest scenario at `e2e/tests/security/test_nft_sec_03_mavlink_signing.py`. AP-only.
|
||||
- Three sub-cases (sent in order; pause between each):
|
||||
- (a) Runner crafts and sends an unsigned `GPS_INPUT` to AP SITL.
|
||||
- (b) Runner crafts and sends a `GPS_INPUT` signed with a wrong-key passkey.
|
||||
- (c) Runner replays a captured signed `GPS_INPUT` from a prior `.tlog` (counter-replay attack).
|
||||
- For each: assert AP emits `BAD_SIGNATURE` STATUSTEXT within ≤500 ms; AP's GPS state does NOT update from these messages.
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
- All three sub-cases.
|
||||
- mavproxy STATUSTEXT capture for `BAD_SIGNATURE`.
|
||||
- AP GPS state read for the no-update assertion.
|
||||
|
||||
### Excluded
|
||||
- iNav variant — N/A; iNav has no MSP signing.
|
||||
- Signing handshake setup — owned by FT-P-09-AP (AZ-416).
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
**AC-1: tier guard**
|
||||
Given `fc_adapter == inav`
|
||||
Then the test SKIPs.
|
||||
|
||||
**AC-2: unsigned rejection**
|
||||
Given the runner sends an unsigned `GPS_INPUT`
|
||||
Then AP emits `BAD_SIGNATURE` (or equivalent rejection STATUSTEXT) within ≤500 ms; AP's `GLOBAL_POSITION_INT` does NOT update.
|
||||
|
||||
**AC-3: wrong-key rejection**
|
||||
Given the runner sends a `GPS_INPUT` signed with a wrong-key passkey
|
||||
Then same as AC-2.
|
||||
|
||||
**AC-4: replayed-message rejection**
|
||||
Given the runner replays a captured signed `GPS_INPUT` from a prior `.tlog`
|
||||
Then same as AC-2 (signing's monotonic counter prevents replay acceptance).
|
||||
|
||||
**AC-5: vio_strategy parameterization**
|
||||
Given conftest parameterization
|
||||
Then the scenario runs once per `vio_strategy` (the SUT's VIO is irrelevant here — runner is the sender).
|
||||
|
||||
## System Under Test Boundary
|
||||
|
||||
The "SUT" here is the AP's signing-acceptance behavior. The probe is at the AP boundary.
|
||||
|
||||
- **Allowed**: runner-crafted MAVLink messages (a public protocol surface).
|
||||
- **Forbidden**: monkeypatching AP's signing logic.
|
||||
|
||||
## Constraints
|
||||
|
||||
- The `BAD_SIGNATURE` STATUSTEXT regex matches the AP-emitted text (e.g. "MAVLink: BAD_SIGNATURE" or equivalent — the exact string is canonical to AP and recorded in the test fixture).
|
||||
|
||||
## Document Dependencies
|
||||
|
||||
- `_docs/02_document/tests/security-tests.md` § NFT-SEC-03
|
||||
- `_docs/02_document/tests/test-data.md` § Security (NFT-SEC-03 row)
|
||||
@@ -1,63 +0,0 @@
|
||||
# NFT-SEC-04 — OpenCV CVE-2025-53644 + AddressSanitizer fuzz
|
||||
|
||||
**Task**: AZ-439_nft_sec_04_opencv_cve
|
||||
**Name**: Crafted JPEG (CVE-2025-53644) does NOT crash; ≥4 h ASan fuzz no findings (RESTRICT-CVE-1)
|
||||
**Description**: Implement NFT-SEC-04 — Tier-1 OR Tier-2; (a) feed `cve-jpeg-fixture` to nav-camera input and assert no crash + graceful error; (b) run an AddressSanitizer-instrumented build under fuzz inputs for ≥4 h with no ASan findings.
|
||||
**Complexity**: 5 points
|
||||
**Dependencies**: AZ-406, AZ-407 (cve-jpeg-fixture), AZ-444 (optional Tier-2)
|
||||
**Component**: Blackbox Tests / Security (epic AZ-262)
|
||||
**Tracker**: AZ-439
|
||||
**Epic**: AZ-262 (E-BBT)
|
||||
|
||||
## Problem
|
||||
|
||||
The pinned OpenCV version (≥4.12) must be CVE-immune to the documented vulnerability (RESTRICT-CVE-1). Without a probe + fuzz validation, regressions on a future OpenCV bump could silently reintroduce a security defect.
|
||||
|
||||
## Outcome
|
||||
|
||||
- pytest scenarios at `e2e/tests/security/test_nft_sec_04_opencv_cve.py` (probe) and `test_nft_sec_04_asan_fuzz.py` (long-running fuzz, gated behind release-gate flag).
|
||||
- Probe (always run): push `cve-jpeg-fixture` as a single nav-camera frame; assert no crash; assert SUT either decodes it or returns a graceful error event in FDR.
|
||||
- Fuzz (release-gate): run `build_kind=ASan` SUT image with a randomized JPEG-fuzz harness for ≥4 h; assert 0 ASan findings.
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
- CVE-probe sub-test (always run).
|
||||
- ASan-fuzz sub-test (release-gate, gated by `RELEASE_GATE=true` env flag).
|
||||
|
||||
### Excluded
|
||||
- General fuzzing of non-image inputs — out of scope.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
**AC-1: CVE probe — no crash**
|
||||
Given the SUT is fed `cve-2025-53644.jpg` as a nav-camera frame
|
||||
Then the SUT does NOT crash; the SUT process remains alive after the frame; the FDR contains either a decode-success record OR a `frame-decode-error` record (graceful error).
|
||||
|
||||
**AC-2: ASan fuzz no findings**
|
||||
Given the `build_kind=ASan` SUT image is running fuzz inputs for ≥4 h
|
||||
Then 0 ASan findings (heap-buffer-overflow, use-after-free, etc.) appear in the captured stderr / ASan log.
|
||||
|
||||
**AC-3: ASan fuzz coverage**
|
||||
Given the 4 h fuzz run
|
||||
Then the fuzz harness reaches ≥1000 unique JPEG corpus inputs (a coverage proxy via `--corpus-info` or equivalent) — informational only; no hard threshold.
|
||||
|
||||
**AC-4: parameterization**
|
||||
Given conftest parameterization
|
||||
Then the probe runs per `(fc_adapter, vio_strategy)`; the fuzz runs once per `vio_strategy` (fc_adapter is irrelevant for image-decode).
|
||||
|
||||
## System Under Test Boundary
|
||||
|
||||
End-to-end through public boundaries; the ASan fuzz uses the SUT's own image-decode path (no direct OpenCV calls from the harness).
|
||||
|
||||
- **Allowed**: nav-camera frame push (a public input), ASan log capture, FDR archive read.
|
||||
- **Forbidden**: directly testing `cv2.imdecode` outside the SUT.
|
||||
|
||||
## Constraints
|
||||
|
||||
- Fuzz duration is ≥4 h per RESTRICT-CVE-1; default CI run uses the probe only (~30 s) and gates the fuzz behind `RELEASE_GATE=true`.
|
||||
|
||||
## Document Dependencies
|
||||
|
||||
- `_docs/02_document/tests/security-tests.md` § NFT-SEC-04
|
||||
- `_docs/02_document/tests/test-data.md` § Security (NFT-SEC-04 row)
|
||||
Reference in New Issue
Block a user