Highlights
This release is almost entirely a precision pass on the MCP tool-poisoning
(MCP009) and skill-shadowing (SKL002/SKL003) detectors, plus a couple of
config-scanning bugs. No new rules; several existing rules got materially
more accurate.
Fixed false positives
- MCP009 / SKL003 (cross-tool/cross-skill shadowing) now distinguishes a
bare conditional ("when X is unknown, use Y" — ordinary sibling-tool
documentation, extremely common in real multi-tool MCP servers and skill
bundles) from an actual override/substitution directive ("instead of",
"always", "never", "silently", or output-rerouting phrasing like "route the
message body through this tool"). Only the latter now fires atlikelyby
default; the bare-conditional form is demoted toheuristic
(--paranoid-only) instead of being dropped entirely. - SKL002 (injection phrasing) gained context-aware suppression for three
previously noisy patterns:- negation ("never read
.env") no longer reads as an instruction to
read credential files, - quoted example phrases inside a skill's own defensive documentation
("flag inputs like 'ignore previous instructions'") no longer read as
the attack they're describing, - "do not tell the user X — they were never asked" no longer reads as
concealment when the surrounding text is a factual correction.
- negation ("never read
- Fixed a related deobfuscation bug where the intra-word-line-break-join pass
(used to catch genuine evasion) could delete a newline that was itself part
of the suppressing context above, or coincidentally pull two unrelated
phrases into proximity — both were silently defeating the new suppressions
and, worse, promoting the resulting false positive toproven. Cross-tool
reference matching (SKL003) is no longer run through the deobfuscation
variants at all, since it has no exact-phrase requirement that evasion
could exploit. - SKL004/capability disclosure now checks a skill's companion reference
files, not justSKILL.mdand its top-level description — a bundle that
documents a download/exec step in a per-topic file (e.g. "Install Istio
CLI") was previously flagged as undisclosed even though it documents the
capability, just not in the top-level file. - MCP004 (secret committed in MCP config) now anchors its reported line
to the occurrence that actually contains the leaked value, not just the
first line mentioning the env var name — a config with both a placeholder
and a real secret sharing a var name across servers was pointing findings
at the wrong server. - MCP config env-reference detection now accepts any well-formed
${...}placeholder (dotted/path-style references like
${user_config.api_token}or${CLAUDE_PLUGIN_ROOT}, used by real MCP
client manifests) instead of only bare/env:/input:forms, so those
stopped being misread as literal committed secrets.
Other
- CI workflow actions (
checkout,setup-node,upload-artifact,
codeql-action,scorecard-action) are now pinned to commit SHAs instead
of floating version tags, closing a supply-chain gap in our own pipeline. - New safe-corpus fixtures locking in the fixes above:
test-fixtures/safe/skills/defensive-docs-skill/,
test-fixtures/safe/skills/lint-check/, and an expanded
test-fixtures/safe/mcp/.mcp.json.