feat(sentry): redact bare rootkey-shaped tokens with an exact-shape base64-22 rule#196
Open
gmaclennan wants to merge 1 commit into
Open
feat(sentry): redact bare rootkey-shaped tokens with an exact-shape base64-22 rule#196gmaclennan wants to merge 1 commit into
gmaclennan wants to merge 1 commit into
Conversation
…ase64-22 rule Enables the detection deliberately disabled in #111. The rootkey crosses the wire as strict base64 of 16 bytes (backend/index.js enforces /^[A-Za-z0-9+/]{22}==$/), and any valid 16-byte base64 ends its 22nd char in [AQgw], so the rule matches exactly 22 base64/base64url chars ending there, optionally ==-padded, bounded by non-base64 chars. Padded matches always redact; unpadded ones also need mixed case plus a digit/symbol and must not be pure hex, which spares 32-hex trace ids, 16-hex span ids, PascalCase exception type names, ERR_* codes, error_class tag values, and base64-ish ids of other lengths. Applied identically to both hand-mirrored scrubber copies and to the forbidden-metric tag-value gate; shared cases in test-support/scrubber-cases.js cover both suites. Closes #77
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #77.
PR #111 landed the PII scrubbers with one rule deliberately disabled: a broad "any 22+-char base64 run" meant to catch a bare rootkey with no
rootKey=marker. It over-matched 32-hex trace ids, PascalCase exception type names, anderror_classmetric tags, so bare unmarked rootkeys passed through unredacted.This enables a much narrower rule built from the rootkey's actual shape. The key crosses the wire as strict base64 of 16 bytes —
backend/index.jsalready enforces/^[A-Za-z0-9+/]{22}==$/— and any valid 16-byte base64 must end its 22nd char inA/Q/g/w(the final 4 bits are padding zeros). The rule therefore matches exactly 22 base64/base64url chars ending in[AQgw], optionally==-padded, bounded by non-base64 chars. A padded match is the exact wire shape and always redacts. An unpadded match must additionally show a random-key character mix: both cases, at least one digit or symbol, and not pure hex. That structurally spares trace/span ids (wrong length, hex), exception type names andERR_*codes (letters-only or single-case),error_classvalues, and base64-ish ids of other lengths (43-char public keys, 52-char project ids).Known limits, documented in
docs/sentry-integration.md§8: roughly 1% of random rootkeys are all-letters and would slip through in unpadded form (the padded wire form is always caught — verified over 200k random keys: 0 padded misses, 1.29% unpadded), and a 22-char mixed-case identifier containing a digit that happens to end in[AQgw]is falsely redacted — accepted, since false negatives are worse here.The rule is implemented identically in both hand-mirrored scrubber copies (
src/sentry-scrub.ts,backend/before-send.js) and also gates metric tag values inisForbiddenMetric. Shared cases intest-support/scrubber-cases.js(consumed by both the jest and node:test suites) cover: padded and unpadded bare rootkeys redact, JSON-quoted rootkey values redact, and trace/span ids, type names, 22-char PascalCase identifiers, 22-char hex fragments,ERR_*codes,error_classtags, and 43/52-char tokens all survive.Verified with
npm run lint,npm run build,npm run test(79 passed), andnpm run backend:test(83 passed).