Snyk's ToxicSkills Audit: 13.4% of Public Skills Are Vulnerable
$ grep -n "^##" 2026-05-snyk-toxicskills-audit.md>
I install skills. Other people's skills, into agents that have read access to my entire codebase and a terminal that will run whatever I approve. I publish them too — I maintain a private marketplace that my agents pull from, and on any given afternoon I'm orchestrating four or five Claude Code instances across different projects, each one a click away from running code I didn't write and barely read.
Every one of those installs is a small act of trust. I hit "yes," the skill lands, the agent gets a new capability. I do this constantly, and for a long time the honest version of my threat model was: the marketplace probably checked, right?
Then Snyk published the numbers, and "probably checked" stopped being a sentence I could finish.
Their security research team put out ToxicSkills, an ecosystem-wide audit of public Claude Code skills. They didn't sample. They went wide:
- 3,984 public Claude Code skills audited.
- 534 (13.4%) contained at least one critical-level security issue.
- 76 were confirmed malicious payloads, validated with a human-in-the-loop review.
Roughly one in seven public skills carries a critical-severity flaw. Seventy-six of them aren't sloppy — they're hostile, written to do harm to whoever installs them. That's the population I'd been pulling from with a shrug.
I've spent twenty years building production systems, and the shape of this is painfully familiar. If your developers can install arbitrary skills from a public source, you have an unmanaged supply-chain attack surface. I lived through npm install becoming the most dangerous command in web development. We're doing it again, with agents that can run a shell.
Read the numbers honestly
Before I scared anyone with the wrong figure, I went back and read the report twice — because the headline and the body don't say the same thing.
Snyk's headline mentions "1,467 malicious payloads." The body draws a line the headline glosses over. 1,467 is the count of skills with security flaws at any severity — dependency CVEs, weak permissions, over-broad capability declarations. 76 is the count the team verified as deliberately malicious through manual review. Those are two different animals, and I'm not going to blur them to make a point land harder. When I mean "intentionally hostile artefact," I'll say 76. When I mean "critical-severity issue in any skill," I'll say 13.4% / 534.
The audit also documented an earlier precursor — around 30 directly malicious skills bundled together — distinct from the much larger, named campaign that surfaced a few weeks later. Which brings me to the part that actually kept me up.
ClawHavoc is the separate, scarier story
The campaign worth losing sleep over isn't even in the Snyk report. Koi Security coined "ClawHavoc" for a coordinated supply-chain attack on the OpenClaw skill marketplace — initially 335+ malicious skills, with Antiy CERT subsequently counting 1,184 variants classified as Trojan/OpenClaw.PolySkill. Typosquatting. Dependency confusion. Backdoored utility skills, all running with whatever permissions a developer happened to grant when they hit "yes" on the install prompt.
Which is the part that stings, because the install prompt is the exact muscle memory I've trained into myself. The Snyk audit was a census. ClawHavoc is an active campaign. Both are real, neither shares an attribution, and both belong on the same threat board.
Two more incidents I'd keep there alongside them:
- MedusaLocker via Claude Code skills. Cato Networks documented ransomware operators packaging MedusaLocker payloads as helpful-looking utility skills.
- Silent codebase exfiltration. Mitiga and Datadog Security Labs have both published variants where the skill does the visible task correctly while quietly exfiltrating source to an attacker endpoint in the background. That second one is the nightmare for someone like me — the agent looks like it's working, and it is, right up until you notice your repo left the building.
None of this is theoretical. All of it is in the last six months of advisory write-ups.
What I actually changed
So I went back to my own setup and asked the uncomfortable question: if I got hit by one of these tomorrow, what would have caught it? The answer was "nothing automated," and that was the whole problem. Three controls fixed it. I run all three now.
1. strictKnownMarketplaces. This is the load-bearing setting in Claude Code's plugin marketplace documentation. It takes a boolean true (block any marketplace not in your allow-list) or an array of explicit marketplace descriptors. The part that matters for a team: it's an enterprise-managed setting — individual developers can't bypass it from their own settings.json. Given how casually I hit install, taking that decision out of my own hands is the point.
{
"strictKnownMarketplaces": [
{ "name": "internal", "source": "git@github.com:yourorg/skills-marketplace.git" }
]
}
That config says skills install only from your internal mirror. Public marketplaces, even the official ones, are off the menu unless you explicitly add them. Pair it with the private marketplace pattern I've written about before and you have something a regulator can actually audit — which, in Singapore, you will eventually be asked to.
2. Pin commit SHAs, not @latest. Every skill in your mirror gets pinned to a specific commit hash. Not a tag, and definitely not a moving reference. This is the same hygiene that survived colors.js, faker.js, and ua-parser-js on npm: the latest version is whatever the attacker pushed last night. @latest is a CVE waiting for an opportunity. A pinned SHA is a contract — the skill I vetted is the skill that runs.
3. Quarterly AppSec re-vetting. A pinned SHA is the right starting position, but it doesn't keep the skill safe forever, and this is where I'd been fooling myself. New CVEs land in transitive dependencies every month. A skill's behaviour can get re-classified as malicious once threat intel catches up to it. The honest cadence is quarterly: re-run the scanner over every pinned skill, re-vet anything that's been updated upstream, and only re-pin after the rescan passes.
The CI pattern
The tool I wire into the scanner is snyk-agent-scan — originally Invariant Labs' mcp-scan, now maintained under Snyk after the acquisition. It explicitly supports Claude Code skills in its current agent matrix. The minimal CI job:
# .github/workflows/skills-revet.yml
name: Quarterly Skills Re-vet
on:
schedule:
- cron: "0 9 1 */3 *" # 09:00 UTC, 1st of every 3rd month
workflow_dispatch:
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install snyk-agent-scan
run: pipx install snyk-agent-scan
- name: Scan all pinned skills
run: |
uvx snyk-agent-scan@latest --skills \
--fail-on-severity critical \
--output-format sarif > skills-scan.sarif
- uses: github/codeql-action/upload-sarif@v3
with: { sarif_file: skills-scan.sarif }
It fires on the first day of each quarter, scans every skill in the mirror, fails the workflow if anything critical turns up, and uploads SARIF so GitHub's code-scanning dashboard becomes the audit trail. That last bit is the part to show an auditor: quarterly automated re-vetting, scanner output in SARIF, retained in CI history. That's what supply-chain hygiene looks like once it's evidence instead of a good intention.
The regulatory framing
For regulated teams in Singapore — and that's the lens I default to now — supply-chain risk sits squarely inside the MAS Technology Risk Management Guidelines. Software dependencies, third-party components, ongoing assurance: explicit obligations, all of them. The MAS Information Paper on AI Model Risk Management (December 2024) extends the same principles to AI components — independent validation, ongoing monitoring, change-management discipline. Agent skills are software dependencies. Treating them as anything less is a finding waiting to happen.
For everyone else: ship the boring controls before the ecosystem matures further. OWASP has drafted an Agentic Skills Top 10, which tells you where the industry expects standards to land. Far better to have strictKnownMarketplaces, pinned SHAs, and a quarterly CI job in place before that becomes an audit checklist than to retrofit them after.
Here's where this lands for me. The interesting question with agents stopped being "can the AI do the work?" a while ago — it clearly can. The bottleneck moved to "can a human verify it before it acts?" A malicious skill is that question turned hostile: it weaponises the exact moment of trust I perform a dozen times a day when I hit "yes" on an install prompt. Snyk just measured how often that trust is misplaced. One in seven, with critical severity.
I still install skills. I still publish them. I just stopped pretending the marketplace was doing my verification for me.
The Cutler.sg Newsletter
Weekly notes on AI, engineering leadership, and building in Singapore. No fluff.
The 30 Principles for Agentic Engineering — Part 4: Governance and Safety
Principles 21–25. The governance and safety layer: strictKnownMarketplaces, no goal-conflict prompts, quarterly AppSec, four telemetry signals, monthly incident discipline.
AI Reviews AI Is Not a Review: The Trust Trap Regulators Won't Accept
AI-reviews-AI looks like a control. Under MAS, the EU AI Act, and any reasonable audit, it isn't. Here's why your compliance team won't accept it — and the compensating controls that actually work.
The Governance Wall: Why Most AI Agents Can't Reach Production
The prototype-to-production gap for AI agents isn't technical — it's governance. Most organisations have nothing in this layer. The companies that build it first win the enterprise market. Everyone else stays in pilot purgatory.