blaze-host: document capture, sanitization, and what the tests do not cover

This commit is contained in:
funman300
2026-08-11 02:16:11 +00:00
parent c84fd14cac
commit fafa2f1858
+64
View File
@@ -227,3 +227,67 @@ The script says so explicitly, in one of two forms:
no remote peer connected — only loopback (or nothing) reached Rust
=> a FIFA session did NOT land here
```
## Raw frame capture (opt-in)
Evidence infrastructure, off unless `OPENFUT_BLAZE_CAPTURE` names a file.
```bash
OPENFUT_BLAZE_CAPTURE=/home/alex/OpenFUT/captures/gate7.ofcap ./sidecar.sh start
```
Two layers, deliberately:
```
live FIFA traffic
├── raw capture exact RX/TX bytes, mode 0600, gitignored — NEVER commit
└── blaze-sanitize → repository-safe, replayable fixtures
```
The raw file is forensic evidence and does contain session material; that is
what makes it worth keeping and why it never leaves the machine unsanitized.
**Format.** Deterministic, big-endian: a 20-byte file header, then per-frame
records with connection id, a global monotonic sequence, timestamp, direction
and the exact frame bytes. RX is recorded as received; TX only *after* a
successful write, so a record means the bytes were sent, not intended.
Component, command, msgNum, msgType and payload length are **not** stored beside
the frame — they are already in its 16-byte header, and a redundant copy can
disagree with the bytes, leaving a reader unable to tell which is true.
`Record::header()` derives them.
### Sanitizing
```bash
./target/debug/blaze-sanitize captures/gate7.ofcap -o gate7.jsonl --report gate7.txt
```
Redacts only the named tags (`KEY`, `AUTH`, `SESS`, `MAIL`, `PML`) and reports
every substitution with path, kind and byte length. Replacement is
**length-preserving**, so the TDF varint, payload length and Fire2 header are
unchanged and the sanitized frame is exactly the size of the captured one —
asserted per frame, failing rather than emitting a subtly different
conversation. Frames with nothing sensitive keep their exact wire bytes.
Payloads that will not decode are passed through *and reported*, so a reader
knows they were never inspected rather than assuming they were checked clean.
Real run: 101 frames in, 9 redacted, 13 redactions; two live session keys
present in the raw capture, zero in the sanitized output.
### What the tests do and do not cover
Nine cases, all passing: capture off produces no artefact; RX and TX captured
exactly; ordering preserved; fragmented input (one byte at a time) reconstructs
the same frames as a single write; coalesced input is captured per frame rather
than per read; capture does not alter wire output; sanitization removes a real
session key from a real captured login; malformed/truncated/wrong-version
captures fail clearly; every listed sensitive tag is provably reachable.
Mutation-tested: dropping TX capture, truncating captured frames to their
header, and removing `KEY` from the sensitive list each turn the suite red.
**One mutation is not caught:** moving the TX capture above the write. It is
indistinguishable while writes succeed and diverges only when one fails, where
it would record a frame the client never received. That invariant is held by
code placement and a comment, not by a test.