Harden check_public_safety.py against scanner evasion classes - #34
Merged
Conversation
Adversarial review during the skills#27 run (PR #32) surfaced evasion classes shared by every blocklist entry. Harden the scanner with a regression test per category: 1. Separator/boundary evasion: compound token and private-reference patterns now use (?<![A-Za-z0-9]) / (?![A-Za-z0-9]) edge guards instead of \b (which underscores defeated) and a broadened [^A-Za-z0-9]* inter-part separator, plus HTML-comment stripping, so dot/slash/plus/em-dash/repeats/markdown/comments no longer split a token. Leading/trailing guards keep ordinary prose clean. 2. Cross-line splits: adjacent lines are rejoined and re-scanned for token and private-reference rules; only matches that span the join are reported (allowlisted wrapped URLs stay clean). 3. Unicode: expanded the invisible-character set (invisible operators, CGJ, bidi controls, VS supplement, tag chars) and added NFKC plus Greek/Cyrillic confusable folding. 4. NUL handling: a NUL alone no longer hides an otherwise-decodable text file; only genuinely-binary (undecodable) content is skipped. 5. Decoding: decode_until_stable uses unquote_plus, more passes, and now resolves JS/JSON \uXXXX/\xHH and CSS \HH escapes. The scanner's suppression mechanism and self-non-matching source property are preserved (full-repo scan stays clean). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
next-devin
marked this pull request as ready for review
July 24, 2026 02:43
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (2 files)
Reviewed by minimax-m3 · Input: 48.7K · Output: 1.7K · Cached: 136.7K |
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 #33. Follow-up to the scanner blocklist added in #32 (skills#27).
Hardens
scripts/check_public_safety.pyagainst the evasion classes anadversarial Codex review flagged. Each category lands with a dedicated
regression test, and the scanner's per-line suppression mechanism and
self-non-matching source property are preserved (the full-repo scan stays
clean, verified in CI-style locally).
What changed, by category
1. Separator & word-boundary evasion. Compound token and private-reference
patterns now wrap each body in
(?<![A-Za-z0-9])/(?![A-Za-z0-9])edgeguards instead of
\b(which surrounding underscores defeated), and join theirparts with a broadened
[^A-Za-z0-9]*separator. HTML comments are strippedduring normalization. So
.,/,+, em-dash, repeated separators, markdownemphasis,
_token_, and injected<!-- -->no longer split a token — while theedge guards keep ordinary prose (
threadbare earth,ecommerce operations)clean.
2. Cross-line splits. Adjacent lines are rejoined with a single space and
re-scanned for the token and private-reference rules; only matches that actually
span the join are reported (at the first line of the pair). Wrapped allowlisted
URLs do not fabricate a repo name across the break.
3. Unicode normalization. Expanded the invisible-character set (invisible
math operators incl. U+2062, combining grapheme joiner, bidi controls, the
variation-selector supplement U+E0100–U+E01EF, and the deprecated tag block),
and added Unicode NFKC plus Greek/Cyrillic confusable folding so fullwidth and
homoglyph forms fold to ASCII before matching.
4. NUL-byte skip. A NUL alone no longer hides an otherwise-decodable text
file (the previous whole-file evasion). Only genuinely-binary content — bytes
that fail UTF-8 decoding and carry a NUL — is skipped like binary media; other
undecodable files still surface as
unreadable.5. Decode coverage.
decode_until_stablenow usesunquote_plus, runs morepasses, and additionally resolves JS/JSON
\uXXXX/\xHHand CSS\HHescapesequences.
Scope notes
too, so folding can only add detections, never mask one.
executive/private reference is intentionally left as-isto avoid false positives on the common English word.
Testing
python3 -m unittest discover -s scripts/tests— 32 tests pass (10 newcategory tests), and
python3 scripts/check_public_safety.pyreports no hits onthis branch.