Repository navigation
fix(purchase): limit each stored-note slot to its writer's alphabet - #1820
Conversation
Some variable slots in the stored-error allowlist used broad classes ([^;\s]+, \S+, "[^"]*"), which accept vertical tabs, NUL, NBSP, U+2028 and other format characters, and the unknown-provider slot accepted any text including newlines. Each slot now admits only what its writer produces: Postgres UUIDs for plan, execution and cloud-account IDs, a provider ID alphabet for commitment IDs, the closed resource-type grammar for the EC2 zonal note, a short token for an unknown provider name, and Go %q output for the operator's quoted reason. Anything else falls back to the category message, as before. The allowlist comment now states the rule. Test fixtures that used non-UUID IDs now use the real shape. Closes #1721 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 59 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
|
APPROVED 87de708 by claude-ui-fix-2 Cold review of #1721 (+67/-15, Zero-width, bidi and control characters: closed
HomoglyphsThe ID, provider and resource-type slots are ASCII-only, so a Cyrillic or Greek look-alike can't impersonate an ID. The free-text Length limitsEach ID class is bounded (256, 32 and the fixed UUID length). The reason pattern is unbounded Legitimate messages still renderThe real ID shapes pass verbatim in Attacks tried (reading)
CI at this SHA was still running when I posted (4 pass, 32 pending). The gate needs it green. |
|
APPROVED bbaf49b by claude-ui-fix-2 Merge-only delta from my approval at
CI at this SHA was still running when I posted (1 pass, 35 pending), and the gate needs it green. |
|
APPROVED bbaf49b by claude-darling Cold review; I did not write this change. I reviewed 87de708. bbaf49b is a merge of main (a392f7e) that leaves the PR's own diff identical. From main, the only render-path change is a Redshift retry gate in Source to render
Attacks
Findings
Probes at 87de708 (each reverted, tree clean afterwards)
Runs
|
Some variable slots in the stored-error allowlist used broad classes
([^;\s]+, \S+, "[^"]*"), which accept vertical tabs, NUL, NBSP, U+2028
and other format characters, and the unknown-provider slot accepted any
text including newlines. Each slot now admits only what its writer
produces: Postgres UUIDs for plan, execution and cloud-account IDs, a
provider ID alphabet for commitment IDs, the closed resource-type grammar
for the EC2 zonal note, a short token for an unknown provider name, and
Go %q output for the operator's quoted reason. Anything else falls back
to the category message, as before. The allowlist comment now states the
rule. Test fixtures that used non-UUID IDs now use the real shape.
Closes #1721
Verification
Local at 87de708 (rebased on c376828):
go vet, unit tests forinternal/purchaseandinternal/api, integration tests matching Sanitize/StoredError/Note, andgolangci-lintoninternal/purchaseall pass. The rebase kept main's new Redshift refusal notes. They are fixedregexp.QuoteMetaconstants, so they add no variable slot. The new testTestSanitizeStoredError_SlotsRejectWhitespaceAndControlsfills every slot with whitespace, line breaks, NUL, NEL, NBSP, U+2028 and a zero-width space and checks none passes verbatim, and checks the real ID shapes still do.🤖 Generated with Claude Code