No zero-width characters in source files
Reject source files containing zero-width Unicode characters:
| Codepoint | Name |
|---|---|
| U+200B | ZWSP - zero-width space |
| U+200C | ZWNJ - zero-width non-joiner |
| U+200D | ZWJ - zero-width joiner |
| U+FEFF | BOM / zero-width no-break space (when NOT at position 0) |
These render invisibly yet count as identifier characters in some
parsers - varname and varname (containing a ZWNJ) are different
symbols. Attack shape: a function whose name looks like one already
in scope but resolves to a different definition the attacker controls.
AI-pasted snippets are a common delivery channel.
A leading U+FEFF (file position 0) is a UTF-8 BOM and is handled by
the separate encoding/no-bom frame - this frame ignores position-0
BOMs to avoid double-reporting.
Fix#
Delete the offending character. On the command line:
LC_ALL=C grep -P '[\x{200B}-\x{200D}\x{FEFF}]' <file>
If your codebase legitimately needs zero-width joiners (rare - Indic / Arabic identifier support), suppress at the file level:
# appframes:disable security/no-zero-width-in-source
Deliberately not flagged#
- ZWJ between two emoji (👩💻) - the standard way to compose one glyph from two. A joiner touching a letter on either side is still reported: that is the identifier forgery this frame exists for.
BLOCK rejects the push. Turn frames on per repo on the dashboard's Policy page - see choosing what the gate checks.
Source on GitHub Live demo How it works Questions: contact@nimblegate.com