SkillJacking Is Real. I Built the Pinning Layer Skills Were Missing.
Agents install skills the way we install packages — except skills have no
lockfile, no signature check, no pinning. That gap is now being exploited.
Security researchers demonstrated SkillJacking: hijacking skill listings on a
popular marketplace so agents installing them executed attacker-controlled
instructions. Their count: 925 skills hijacked from their maintainers,
affecting 134K agents
(air.security write-up).
Trojanized skill campaigns with over a million installs have been reported
since. A skill that was clean when you reviewed it can be re-uploaded tomorrow
with an install.sh, a curl | sh line in its SKILL.md, or quiet
credential-exfiltration code — and your agent would never know.
I built skill-pin-verify to close that gap: a stdlib-only Python CLI that
treats skill tarballs like artifacts worth pinning.
What it does
Three commands:
# 1. Record a pin for a skill you trust
skill-pin-verify record https://example.com/skills/tidy-notes.tar.gz --name tidy-notes
# -> {"name": "tidy-notes", "url": "...", "sha256": "9f2c...e1", "recorded_at": "..."}
# 2. Verify before every install: hash check, then content audit
skill-pin-verify verify https://example.com/skills/tidy-notes.tar.gz --pin 9f2c...e1
# 3. Audit any skill directory or tarball, no pin needed
skill-pin-verify audit ./some-skill --strict
verify downloads the tarball, compares its SHA-256 against your pin, then
extracts it safely and audits the contents. A hijacked skill — same name, new
malicious bytes — fails at the pin check before anything is even extracted.
The audit scans for the tampering signals that matter for skills:
-
Install scripts & lifecycle hooks —
install.sh,setup.sh, npmpostinstallhooks (high severity) -
Remote install instructions —
curl ... | shinsideSKILL.md, the classic prompt-level vector (high) - Possible exfiltration — credential/environment access in the same file as network code (high)
-
Tarball path traversal — absolute paths,
..segments, escaping symlinks are skipped, never extracted, and flagged (high) -
Obfuscation —
base64+exec/eval,__import__tricks, hex-escape runs (medium) -
Network / shell primitives —
curl,socket,subprocess,os.system(medium)
Exit codes are automation-friendly: 0 = pin matches and audit clean,
1 = pin matches but high-severity findings (do not install),
2 = pin mismatch or download failure.
This is not npm audit
npm audit answers: do my dependencies contain known CVEs? It checks
packages you already trust against a vulnerability database.
skill-pin-verify answers a different question, one layer up: is this skill
package itself the thing I reviewed? It is the signature/pinning layer for
skill distribution — the part between "the marketplace lists this skill" and
"my agent runs its instructions." npm audit never looks at skill tarballs
at all.
Install
pip install skill-pin-verify
Python 3.9+, zero dependencies — standard library only, so the verifier
itself has nothing to audit.
MIT licensed. 14 smoke tests, all green. If you maintain a skill marketplace
or an agent that installs skills, pinning is the cheapest defense you are not
doing yet.
Top comments (0)