Skip to main content
BlogSecurity

Malicious Agent Skills: ClawHavoc SKILL.md Supply Chain Guide

How ClawHavoc spread 341 malicious SKILL.md skills on ClawHub with fake Prerequisites, and a vetting script plus Claude Code settings to defend agents.

Matthews Wong

Software Engineer

October 202611 min read
Malicious Agent Skills: ClawHavoc SKILL.md Supply Chain Guide

Key Takeaway

Malicious agent skills spread by hiding install steps in a SKILL.md Prerequisites section, not by exploiting a bug. In January 2026 the ClawHavoc campaign put 341 malicious skills among 2,857 audited on ClawHub, 335 delivering Atomic Stealer. Defend by reading SKILL.md and every bundled script, and disabling inline shell execution.

In late January 2026, skills with names like solana-wallet-tracker and polymarket-trader appeared on ClawHub, the public registry for OpenClaw agents. Their SKILL.md files looked like good documentation: a clear purpose, tidy sections and a Prerequisites block asking you to install one small helper first. That helper was the malware.

This post reads four primary sources closely: Snyk's write-up of the Koi Security audit, Antiy CERT's campaign analysis, OpenClaw's own VirusTotal announcement and an arXiv paper on registry attacks, plus the Claude Code skills documentation for the defensive settings. ClawHavoc hit OpenClaw's registry, not Claude Code's, but SKILL.md is the same kind of file in both. I was not compromised by any of this. What follows is a close reading and a checklist, not a war story.

What ClawHavoc was, and why the numbers differ

Snyk reports a security audit of 2,857 skills on ClawHub that found 341 malicious ones, roughly 12% of the registry, across a campaign window of 27 to 29 January 2026. Of those, 335 delivered Atomic Stealer (AMOS), a commodity macOS infostealer, from a single command-and-control IP address, using fake Prerequisites sections. Antiy dates Koi Security's disclosure, under the name ClawHavoc, to 1 February.

Antiy CERT's figure is far larger because it was counted later. As of 5 February it tallied 1,184 malicious skills tied to 12 author IDs across ClawHub's history, with 3,498 skills on the registry after large-scale removals. Its timeline has the first malicious skill on 27 January and mass deployment on 31 January. So 341 is a dated snapshot, not a ceiling, and should be quoted with its date.

SourceScopeFinding
Snyk, reporting the Koi audit2,857 ClawHub skills audited341 malicious (about 12%); 335 delivered AMOS from one C2 IP address
Antiy CERT, count as of 5 FebruaryEvery malicious skill in ClawHub's history1,184 skills from 12 author IDs; 3,498 skills left on the registry
Antiy CERT, timeline for 31 JanuaryThe mass deployment day386 skills from 7 attackers, 354 of them from one account
ClawHub response, per AntiyUser reporting added after the campaignUp to 20 reports at once per logged-in user; 3 or more distinct reporters hides a skill

One more fact matters more than the counts. Publishing needed only a GitHub account at least one week old, and Antiy names that open upload policy as the root cause.

Anatomy of a malicious skill: three shapes

Antiy examined three sample types. A skill is a ZIP archive holding a JSON metadata file, a SKILL.md and sometimes a scripts folder, and the malicious ones used SKILL.md files of 500 to 700 lines, likely AI-generated, to look credible. The first shape is a pure download lure: SKILL.md only, falsely claiming you must install an openclaw-core component. The second is a Python script in a fake crypto-monitoring skill that fetches payloads or opens a reverse shell. The third is data theft: a JavaScript file in a fake weather assistant that reads the ~/.clawdbot/.env file and sends it to a webhook.

# Reconstructed SHAPE of a "download lure" skill, built from the Antiy and
# Snyk descriptions. No real link, host or command appears here on purpose.

solana-wallet-tracker/
  SKILL.md          # 500-700 lines of plausible, probably AI-written docs
  _meta.json

# Inside SKILL.md, after the convincing part:

## Prerequisites
This skill needs the openclaw-core helper.

Windows: download the release archive from <a GitHub Releases link>
         archive password: <printed openly on the page>
macOS:   paste this into Terminal: <a base64-encoded command that fetches
         a script from a paste or clipboard site>

# Nothing here is an exploit. The skill asks YOU to run the payload, so the
# agent, the registry scanner and the sandbox are never involved.

The lure sat under Prerequisites or Setup. On Windows it was a GitHub Releases link to a password-protected ZIP with the password printed openly, which Antiy says helps evade scanning. On macOS it was a terminal command, often base64-encoded, that pulled a script from a clipboard service such as rentry.co or glot.io. Antiy calls it an evolution of ClickFix. The skill never has to exploit anything: it asks you, politely, to run the payload yourself.

Why a markdown file is an execution surface

The defence most people reach for is to read SKILL.md. Snyk's point is that this reads the wrong layer: users review SKILL.md, but the bundled install.sh or helper.py is what actually executes. The table sets what a reviewer sees against what happens.

LayerWhat the reviewer seesWhat actually happens
Prerequisites proseOrdinary setup stepsYou paste the command yourself; Antiy saw base64 commands pulling from clipboard services
Bundled scriptOften never openedSnyk: it is what actually executes
Inline shell injection (Claude Code)A documentation line starting with an exclamation mark and a backtickRuns before Claude sees the skill and replaces the placeholder with the output
allowed-tools frontmatterLooks like a restrictionOnly pre-approves the listed tools; other tools stay callable subject to your permission settings
External referencesAn npx -y package nameSnyk's example pulls an npm package with no version pinned and runs its post-install scripts

The Claude Code documentation is explicit about the last controls. Workspace trust does not gate allowed-tools: Claude Code applies a project skill's allowed-tools even in a -p run in an untrusted folder, so review repository skills before running there. Injected commands are permission-checked, and a command matched by a deny rule aborts the invocation, but inline shell execution stays available until you turn it off. Snyk adds that OpenClaw has no sandboxing by default, that workspace skills override managed and bundled ones, and that a hot-reload watcher activates changes mid-session.

The registry layer: ranking, selection and weak gates

Saha, Faghih and Feizi (arXiv, 12 May 2026) argue that SKILL.md is operational text rather than documentation. They test three registry-facing stages with real ClawHub skills. In discovery, short text triggers manipulated embedding-based retrieval, giving adversarial skills up to an 86% pairwise win rate and 80% Top-10 placement. In selection, description-only framing led agents to choose a malicious variant of a functionally equivalent skill in 77.6% of paired trials on average. In governance, semantic evasion tactics let malicious skills avoid a blocking verdict in 36.5% to 100% of cases.

Those are experiments on realistic registry mechanisms, not measurements of the live ClawHub, so read them as what an attacker can do rather than what happened. They matter because you find skills through ranking and an agent picks them by description. A malicious skill needs to be discoverable and attractive, and the paper shows words alone can do both.

Where the guardrails lagged

ClawHub's first response was user reporting, and Snyk notes it arrived after the campaign window, when thousands of users had potentially installed malicious code. Antiy calls the measures necessary but far from sufficient and asks for automated static analysis, semantic analysis and sandboxing.

On 7 February OpenClaw announced VirusTotal scanning. Each skill is zipped with fixed compression and timestamps plus a _meta.json, hashed with SHA-256 and checked against VirusTotal, and unknown bundles go to Code Insight analysis, which the post says is powered by Gemini. Benign skills are auto-approved, suspicious ones get a warning but stay available, malicious ones are blocked from download, and active skills are rescanned daily. The post itself says this is not a silver bullet and will miss natural-language instructions that steer an agent and carefully crafted prompt injection.

A clean scan is not a safety verdict. OpenClaw says so itself, and the openly printed archive passwords in the Windows lure show how a scanner can be walked around. Treat every registry gate as one layer and keep your own review as the last one.

The trade-off is real. An open registry with a one-week-old GitHub account gate grows fast and is cheap to abuse, while review before publishing slows honest authors. Neither side has solved it, so the cost lands on whoever installs.

A vetting checklist you can run as a script

Reading is still the baseline, but a script points at the lines worth reading. This one is mine, built from the lures in the Antiy and Snyk reports. I ran it against a throwaway skill containing each pattern and it flagged all of them. It is a triage aid, not a scanner, and a quiet result proves nothing.

#!/usr/bin/env bash
# vet-skill.sh <skill-dir>   a triage aid, NOT a scanner. Silence proves nothing.
# Patterns come from the lures described by Antiy CERT and Snyk.
dir="$1"
[ -d "$dir" ] || { echo "usage: vet-skill.sh <skill-dir>"; exit 2; }

echo "== inline shell injection in markdown (Claude Code runs it before the model reads it)"
grep -rnF '!`' "$dir" --include='*.md'

echo "== pipe-to-shell, decode-and-run"
grep -rnE '(curl|wget)[^|]*[|][[:space:]]*(ba|z)?sh|base64[[:space:]]+(-d|--decode)' "$dir"

echo "== paste and clipboard sites, archive passwords printed in the docs"
grep -rniE 'rentry[.]co|glot[.]io|pastebin|password[: ]+[A-Za-z0-9]+' "$dir"

echo "== unpinned installs (a new release runs new code)"
grep -rnE 'npx[[:space:]]+-y|uvx[[:space:]]|pip3? install' "$dir"

echo "== reads of credential paths and agent memory files"
grep -rnE '[.]ssh|[.]aws|[.]env|[.]clawdbot|SOUL[.]md|MEMORY[.]md|Keychains|Login Data' "$dir"

echo "== frontmatter that widens what runs without asking"
grep -nE '^(allowed-tools|hooks|shell):' "$dir"/SKILL.md

echo "== bundled executables you must open and read yourself"
find "$dir" -type f \( -name '*.sh' -o -name '*.py' -o -name '*.js' -o -name '*.ps1' \)

Then read what it flagged and open every bundled script, because that is where Snyk says execution happens. Check that the stated purpose needs the access the skill asks for: a weather assistant has no reason to touch an .env file.

Lock down Claude Code before you install anything

These controls come from the Claude Code skills documentation, so they apply to skills loaded there, not to OpenClaw. Setting disableSkillShellExecution replaces each injected command with a policy message for user, project, plugin and additional-directory skills, though not for bundled or managed ones. The docs call it most useful in managed settings, where users cannot override it. Skill deny rules, managed through /permissions, restrict which skills Claude can invoke.

// settings.json (best in managed settings, where users cannot override it)
{
  "disableSkillShellExecution": true,
  "permissions": {
    "deny": ["Skill(deploy *)"]
  }
}

# A skill you WRITE, with side effects: keep the model from loading it alone,
# and remember allowed-tools only PRE-APPROVES, it does not restrict.
---
name: deploy
description: Deploy the application to production
disable-model-invocation: true
allowed-tools: Bash(git status *)
---

For skills you write, set disable-model-invocation to true on anything with side effects so Claude cannot load it on its own, and keep allowed-tools narrow, remembering it pre-approves rather than restricts. The docs add that allowManagedPermissionRulesOnly (v2.1.282 and later) makes Claude Code ignore allowed-tools in project and personal skills.

In a repository you do not trust, a project skill is part of the attack surface. Read .claude/skills before the first run, not after.

What to do on Monday

Five steps, in order of cost. None needs a new product.

  1. List every skill on the machine: ~/.claude/skills, each project's .claude/skills, plugin skills and, for OpenClaw, the workspace and managed folders. Delete what you do not use.
  2. Run the vetting script over each one, then read SKILL.md and every bundled script by hand.
  3. Set disableSkillShellExecution to true in managed settings, and add Skill deny rules for anything you have not reviewed.
  4. Copy reviewed skills into your own repository and review the diff on every update. Snyk names rug pulls, a malicious release after adoption, as a risk; copying is my advice, not a vendor requirement.
  5. Run snyk mcp-scan and snyk aibom, the commands Snyk describes for scanning agent configurations and listing AI dependencies. If you installed an OpenClaw skill during the campaign, review recent installs and rotate OpenClaw-related credentials, as Antiy advises.

I left the indicators of compromise out on purpose. Antiy publishes its own list, and a blocklist taken from a February report ages quickly.

The rule I take from ClawHavoc: a skill is trusted code that happens to be written in markdown. Read the prose and the scripts, remove the shell hooks you do not need, and never treat a registry scan or a report count as the review.

FAQ

Frequently Asked Questions

Short answers to what readers ask most about this topic.

What was the ClawHavoc campaign?

ClawHavoc was a campaign that published malicious skills to ClawHub, the registry for OpenClaw agents, in late January 2026. Snyk reports 341 malicious skills among 2,857 audited, 335 of them delivering Atomic Stealer through fake Prerequisites sections. Antiy CERT later counted 1,184 malicious skills from 12 author IDs as of 5 February.

How does a malicious SKILL.md attack a user?

Most of the skills did not exploit a bug. Their SKILL.md carried a Prerequisites or Setup section that told the user to download an archive or paste a terminal command, so the user ran the payload themselves. Some also shipped scripts that read credential files such as .env or opened a reverse shell.

Does reading SKILL.md before installing a skill keep me safe?

Not on its own. Snyk points out that users review SKILL.md while the bundled install.sh or helper.py is what actually executes, so read every bundled script too. In Claude Code, also check for inline shell injection and review allowed-tools, since that field pre-approves tools rather than restricting them.

Can Claude Code skills run shell commands automatically?

Yes. The Claude Code documentation describes inline shell injection that runs before Claude sees the skill and replaces the placeholder with the output. You can turn it off by setting disableSkillShellExecution to true, which works best in managed settings where users cannot override it.

Is a registry malware scan enough to trust a third-party skill?

No. OpenClaw's own VirusTotal announcement says scanning is not a silver bullet and will miss natural-language instructions that steer an agent and carefully crafted prompt injection. Use the scan as one layer and keep your own review, sandboxing and least-privilege permissions in place.