Repository navigation
chore(insurance): harden vendor-text sanitizing and key handling - #339
Conversation
Strip Cf, Zl and Zp in cleanMessage, run Comparison and Plan decode errors through the same clean, redact, truncate pipeline as HTTPError.Message, reject API keys with surrounding whitespace, cap an out-of-range Retry-After, and drop the unreachable empty-key guard. Pin the pipeline order, repeated keys, split keys and the Retry-After boundaries with tests. Closes #286 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Warning Review limit reached
This review includes 3 billable files and costs up to $0.75.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Or wait 18 minutes for your next included review. View limit details
Comment |
|
Gate review (Opus 5.5) at 234e964: non-blocking findings from my own probes (none leaks the plain key;
Heads-up for #338: the textual merge with #338 is clean, but it does not compile. |
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Gate verdict at e545153: CHANGES REQUESTED (1 blocking regression). Blocking: this PR makes
This is the same header/redaction disagreement the whitespace reject was added to prevent. Also accepted: a key made only of Cf ( Otherwise clean at this head:
|
A key with a leading BOM or ZWSP passed the whitespace check, then cleanMessage stripped that character from a vendor echo before redaction ran, so the valid key was printed. Reject any byte outside 0x21-0x7E in newClient, naming the byte position and never the key. Add the end-to-end echoed-header test, drop the decode subtest that never exercised the sanitizer, and narrow the CHANGELOG claim. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Gate verdict at 038d0f8: APPROVED (Opus 5.5 independent review).
|
Closes #286
pkg/insurance only; no exported API change.
cleanMessagealso strips Cf, Zl and Zp (zero-width, bidi override, line/paragraph separators); a test per category.ComparisonandPlandecode errors now go through the same clean, redact, truncate pipeline asHTTPError.Message(sanitizeVendorText), keeping the original in the Unwrap chain (errors.Is(err, errMissing)still works). Decode errors are built in quote.go, which cannot reach the client's redactor.newClientrejects an API key with leading or trailing whitespace (the header and the redaction used different strings).Retry-Afterpast the int range is capped at 24 h (AtoiErrRange) instead of ignored; 86399, 86401 and the overflow case are pinned.>vs>=at the cap is an equivalent mutant.%prule documented at client.go:33-39 (go#338 owns it).Verification (local, httptest fixtures, no live vendor call): 13 of 14 mutants killed, each by a named test (truncate-first, redact-before-strip, clean-after-truncate, each of Cf/Zl/Zp removed,
Replaceonce, both decode bypasses, trim check removed, ErrRange handling removed, cap off-by-one, Unwrap dropped); the survivor is the equivalent>=cap.golangci-lint run ./...andgo test ./...in pkg pass (GOTOOLCHAIN=go1.26.9). After #337, most decode errors withhold vendor values, so the key-as-enum-value test uses a short identifier-shaped key, which is still echoed and is redacted here.🤖 Generated with Claude Code