Egress path filter review corrections: keys, decoding gate, telemetry hash, pointer cardinality
Corrections an independent review found in an outgoing JSON path filter that already validated decoded values, budgeted work and isolated its matcher. Covers scanning key text, the receiver defined decoding gate, a raw bracket pre scan pitfall, a brute forceable telemetry hash, unbounded pointer labels, grammar gaps and scratch copy normalization.
Egress path filter review corrections
Trigger
Use this after an outgoing structured document filter already parses strictly, matches identifying path shapes on decoded string values, meters work from one budget ledger, runs the matcher in an isolated worker, and emits value free rejection records. This skill lists what an adversarial review still found wrong in such a design. Apply it as a checklist before calling the filter done.
The failure it prevents
A design that is correct at the layer level can still leak or falsely deny through six smaller gaps: a path placed in an object key rather than a value, a nested encoding the filter refuses to unwrap but the recipient happily decodes, a depth pre scan that counts brackets inside string literals, a telemetry hash over a low entropy value that the secret holder can brute force, a warning label space that grows with array length or schema recursion, and normalization that rewrites the emitted document rather than a scratch copy.
Steps
- Scan key text with the same grammar used for values, and deny on an unknown key rather than only reporting it. A key is transmitted verbatim by canonical re serialization, so a reported but retained key is a leak.
- State the threat model of the nested decoding gate. Unwrapping only values that fully decode means the filter, not the recipient, decides what counts as encoded. Base64 with one trailing junk character, unpadded variants, UTF 16 text, or compressed payloads all pass as opaque. Document that the filter stops accidental leakage from a cooperative producer and is not exfiltration containment against an adversarial one. Run format character stripping before each decode attempt as well as after, otherwise a zero width character inside an encoded payload defeats the gate while the recipient strips it.
- Do not pre scan bracket depth on raw bytes. A string value full of literal opening brackets would count as deep nesting and cause a false deny, and a string aware pre scan must track escapes correctly or inverts the error. The strict parser with an explicit stack already enforces depth. Drop the pre scan.
- Treat the telemetry hash as an oracle. Identifying path values are structured and low entropy, so anyone holding the keying secret can recover a username from the hash by enumeration. If the telemetry sink holds the secret the hash is a value leak; if only the installation holds it, the sink cannot use it and it becomes a cross day tracking fingerprint. Either drop the hash or salt it with a per window random value so it only detects recurrence inside one window.
- Close the pointer label space. Array indices are unbounded and recursive schemas give unbounded pointer depth, so one record per code per pointer is only nominally bounded. Bucket array indices into a few ranges and truncate pointer depth to a fixed level.
- Fill the grammar gaps. Treat any drive letter followed by a colon as a hit even without a following separator, since drive relative forms are valid. Apply compatibility normalization, strip combining marks, and keep a small confusables table for separator and colon look alikes, because fullwidth and mathematical variants survive a simple slash folding step.
- Normalize on a scratch copy and emit the original strings. Separator folding and case folding exist only for matching. Reject numbers that do not round trip through the canonical serializer rather than silently altering them.
- Harden the worker channel. Treat a clean exit with empty or truncated output as deny. Frame the result with a length prefix and terminator, check exit status only after end of file on the pipe, and drain the pipe concurrently so a document larger than the pipe buffer does not deadlock into a permanent deadline deny. If the allow verdict is persisted in a job queue, write it atomically together with a hash of the exact canonical bytes.
- Cap decoded output during decoding, not after, and charge decoded JSON to the global depth and node counters. Effective depth is unwrap depth multiplied by document depth, so size the explicit stack for the product.
Limits
Paths split across sibling array elements or adjacent fields remain undetected by any per value scan; only a schema that forbids such fields closes that gap. Per window counters still reveal activity rhythm; use coarse buckets if that matters. The design still assumes the recipient decodes only what the filter unwraps, that the worker sandbox denies network and filesystem access, and that canonical bytes leave only through the parent process single send path.
Basis
Reasoned analysis and one independent adversarial review. No tests were executed, no code was run, and no implementation was inspected. Every threshold mentioned is a placeholder the adopting team must derive and test.