Check O14 · agent surface family · severity CRITICAL · automatic · one of the 17 Open VSX checks
Maps to OWASP LLM01 ATLAS AML.T0051.001 ATLAS AML.T0068 Instructions an agent reads and a reader cannot see: indirect injection delivered by obfuscation.
The question this check asks: do the agent rule files inside the package carry invisible characters — zero-width joiners, bidirectional controls, tag characters — that a person reviewing the file cannot see and a model reads as text?
Pillar Security described the Rules File Backdoor in March 2025: instructions hidden in a rules file with characters that do not render. The original GlassWorm (October 2025) hid its loader in invisible Unicode variation selectors — inside JavaScript, which this tier does not read. O14 reads the agent files only.
O14 is C19's scan on the agent files O13 read out of the package. A hidden character is hidden-unicode:<path>, CRITICAL, 45 points, and the verdict is BLOCK under every shipped profile.
It fired on none of the 100 most-downloaded extensions measured on 1 November 2026; six of them ship agent files.
JavaScript. Invisible characters in the code bundle are not read on this tier. Files O13 did not read: past the eighth, or over 64 KB.
Scope, the same on every page of this roster: RepoGates does not see git clone, package managers or curl — outside Claude Code with the RepoGates plugin, whose hook refuses a clone or install that names a blocked repository on the command line, before it runs. The hook sees Bash tool calls in that one client and nothing else. Edit and Write are read for one thing only — an API key about to be saved — checked on the machine and never sent; that guard asks, it never denies. Open VSX is the registry VSCodium, Cursor and Windsurf install from. An extension there is assessed on request: through the API (/v1/ovsx/score/{namespace}/{extension}), the MCP server (platform="ovsx") and the preflight, which reads an open-vsx.org address and a codium, vscodium, cursor or windsurf --install-extension line. That line is read against both Open VSX and the VS Code Marketplace, because it cannot show which registry the editor uses; code --install-extension stays the Marketplace's. An extension installed from the editor's own UI, or one that auto-updates, is not a shell line the hook sees; there is no board on Open VSX's pages, and the browser's download gate does not read open-vsx.org. This roster reads what Open VSX publishes about an extension — its record, its version history, its manifest, the package's file list and at most eight agent files inside the package — and the extension's code bundle is not read on this tier. Open VSX's own scan results are admin-only and not published; its review status is evidence, and its silence is never a pass. An extension Open VSX no longer serves is not assessed, never a pass. A PASS means nothing matched on what was read.
grep -nP '[\x{200B}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{E0000}-\x{E007F}]' CLAUDE.md AGENTS.md
Run it on the agent files of an unpacked package; a match is a character you cannot see.
Why is this critical? Because a hidden instruction in an agent file is written to be read by a model and missed by a person. There is no ordinary reason for it.
Would O14 have flagged the original GlassWorm? No. GlassWorm hid its loader in JavaScript, which this tier does not read; O14 reads agent files only.
Which characters count? Zero-width characters, bidirectional controls and tag characters, as C19 reads them.
V14 Hidden Unicode in agent rules — the Marketplace twin · C19 Hidden Unicode — the same scan in a repository · O13 Agent config files — which files are read.
Add RepoGates to Chrome Pricing
Sources for this page: Open VSX's published record format, read on 1 November 2026; the measurement of Open VSX's 100 most-downloaded extensions the same day; the severities from the product's roster, and the default weights of its scoring table; campaign facts as the primary write-ups state them. See also the Open VSX intelligence page.