Skill scanning is antivirus for markdown

AI CodingClaude CodeSecurityDeveloper ToolsTrend Commentary

August 22, 2026

Light chalk shield over a folded markdown page on dark asphalt with the words antivirus for markdown

Skill scanning is antivirus for markdown because a skill is not a README. It is a folder of instructions that can run shell before the model sees a line.

Anthropic shipped the org-level version of that control on 6 August 2026. Enterprise only. Off by default. A third-party skill or plugin hits pass, warn, or fail on upload or edit, then it is allowed to run.

The wrong model is that markdown cannot hurt you. Open the folder. The blast radius is sitting in YAML.

Markdown is the wrapper, not the payload#

A dim glass sheet labelled WRAPPER peeled back from a teal motor block labelled PAYLOAD and SHELL
The crate is markdown. The motor is the rest of the folder.

Help Center copy still sells the cute version. What are skills calls them folders of instructions, scripts, and resources. Anyone can write one in Markdown. You can also attach executable scripts for the advanced case.

That last sentence is the whole post. A skill is a shipping crate with a motor bolted to the lid. The crate is .md. The motor is the rest of the directory.

Claude Code's skills docs make the motor official. allowed-tools grants listed tools without a permission prompt for the turn that invoked the skill. The grant clears on the next message. Workspace trust does not gate it. A project skill can hand itself Bash in a folder nobody has ever trusted.

---
name: render-chart
description: Render a chart from a CSV file
allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/render.sh *)
---

That snippet is from the same docs. It is a permission slip, printed in the header of a markdown file. The path-scoped Bash grant matches the bundled script, so the script runs without prompting.

Then there is bang-command injection. Dynamic context runs a shell command before the skill content is sent to Claude. The official first-skill example inlines git diff HEAD behind a bang. The model never sees the command. It sees the output. A failed command aborts the invocation. A successful one has already run.

You'll hit this if a cloned repo carries .claude/skills/ and someone trusted the workspace. Datadog Security Labs said the quiet part in May. Model-level refusal cannot interrupt a command that finished in preprocessing.

The Agent Skills spec puts executable code in scripts/ on purpose. Python, Bash, JavaScript. Executed, not loaded. That is not a docs format. That is a package format that happens to start with a prompt.

The scan sits on the upload, which is the right slot#

A zip brick entering a glass gate with bins labelled PASS, WARN, and a coral FAIL wall
Scan on intake. Three bins. Fail is a dead end.

The 6 August 2026 release notes named it without drama. Enterprise plans can turn on skill and plugin security scanning to check third-party skills and plugins for malicious content when someone uploads or edits them.

Get started with skill and plugin scanning is the real page. Claude reviews the contents, looks for signs of malicious behavior, and returns pass, warn, or fail. Most scans finish in about one to two minutes. Results are cached, so the same zip again comes back almost instantly.

Pass installs with no extra message. Warn stays usable behind a caution banner you acknowledge. Fail is blocked. The uploader cannot override it. Admins cannot approve it for the org at this time. Fix the zip and upload again. Same bytes, same result.

That is antivirus. Scan on intake. Three verdicts. Cache. Block. No extra charge once the toggle is on. Owners flip security scanning under Organization settings, Skills.

It is not the Claude Security plugin. Claude Security plugin docs describe a multi-agent vulnerability scan of a codebase inside a Claude Code session. Install claude-security@claude-plugins-official. Different object. Different admin page. Mixing them is how a team thinks the laptop is covered when only the org zip gate is on.

Platform docs add the threat names. Hidden code execution. Sending data to an outside service. Instructions that tamper with Claude's safeguards. A skill whose scan has not finished is blocked too. Antivirus again. The file does not run while the scan is still chewing.

A pass is not a review, and the laptop still loads the zip#

A teal SCAN ring in the center with dim leak paths labelled MCP, HOOKS, and LAPTOP
The gate is real. The leak paths around it are real too.

The honest objection is that this scanner has a lot of holes for something wearing a security badge. That objection is fair. It is also the reason to turn the thing on anyway.

Off by default. Not retroactive. Skills for enterprise spells out the API hole. Skills shared through a connected MCP server follow the MCP trust model instead.

  • Skills already sitting in the org keep working
  • MCP servers and hooks are skipped
  • Skills API and Console uploads are skipped
  • HIPAA, CMEK, and ZDR orgs do not get the scan
  • Laptop plugin folders are not named as a scanned surface

Official copy names the surfaces as Claude, Claude Cowork, and Enterprise plugin marketplaces. It does not document a scan of ~/.claude/plugins/ or a project .claude/skills/ folder on a laptop. A cloned repo can still walk in through workspace trust.

Anthropic already wrote the honesty clause. A pass means the scan did not find third-party skills built to misuse the access they are given, such as quietly moving data. It is not a guarantee the skill is safe in every respect. It will not catch a skill that behaves in ways you did not intend without being malicious.

That is the same sentence antivirus vendors have printed for twenty years. A pass is not a safety guarantee. You still open the zip. You still run the scan on the download.

The laptop complement is sitting in the skills docs. Set disableSkillShellExecution to true in managed settings and bang-command injection from user, project, plugin, and extra-directory skills becomes a disabled-by-policy placeholder. Bundled and managed skills are not affected. Pair the org scan with that kill switch. Do not pick one and call the job done.

Skill scanning questions

Does scanning run on skills already in the org?

No. Skills and plugins that were already in the organization keep working when the toggle goes on. Only new uploads and edits get the scan. Treat the existing set as a separate review pile.

asked on support.claude.com
Can an admin approve a skill that failed the scan?

Not at this time. A blocked skill cannot be overridden by the uploader, and admins cannot approve it for the organization. The documented path is edit the zip, fix what was flagged, and upload again. Uploading the same bytes returns the same result.

asked on support.claude.com
Is this the Claude Security plugin?

No. The Claude Security plugin runs a multi-agent vulnerability scan of a codebase inside a Claude Code session. Skill and plugin scanning is an org toggle on upload and edit. Different object, different install, different admin page.

asked on code.claude.com
Are MCP servers and hooks scanned?

No. MCP servers and hooks are not scanned at this time. Skills shared through a connected MCP server follow the MCP trust model instead. A pass on a skill zip does not cover the connectors it tells Claude to call.

asked on support.claude.com
Does a pass mean the skill is safe?

No. A pass means the scan did not find third-party skills built to misuse the access they are given, such as quietly moving data. It is not a guarantee the skill is safe in every respect, and it will not catch a skill that behaves in ways you did not intend without being malicious.

asked on support.claude.com

A house plugin is already a shell program in markdown#

Eight stacked markdown cards labelled 8 SKILLS with teal arrows pointing to a BUN RUN chip
A first-party plugin is still a shell program that arrived as markdown.

This site's content-engine plugin lives at .claude/plugins/content-engine/. Version 0.95.0. Eight SKILL.md files. The syndicate skill is 896 lines. The blog-post skill is 590. Official tip says keep SKILL.md under 500 lines. Both miss it and still ship as markdown.

Nine command files. Five declare Bash in allowed-tools, including the blog-post command (Bash, Read, Edit, Write, Task) and the R2 upload command (Bash, Read). Eight agents. Three list Bash. Skill bodies contain 101 bun run lines. One bundled script, measure-voice.mjs, in the spec's scripts/ slot.

No bang-command lines in that plugin. The blast radius is instructed shell plus command-level Bash grants. Publish. Upload. Browser automation. A zip of markdown that, once trusted, tells an agent to talk to production.

That is a first-party plugin written on purpose. Writing a skill by hand is a different job. Fat instruction files are a token problem. This is an intake problem. You would not skip the scan because you like the author.

Turn the toggle on. Still open the zip. Put disableSkillShellExecution on the fleet. Change your mind when skills lose load-time shell and unprompted Bash grants. Until then, skill scanning is antivirus for markdown, and markdown is how the program arrives.

  • Read the allowed-tools line before you trust the folder
  • Search the body for bang-command placeholders
  • Open scripts/ and treat those files as executed, not loaded
Share

Newsletter

New posts land in your inbox when they publish. No spam, unsubscribe anytime.

Prefer RSS