hotsa104/skill-firewall
GitHub: hotsa104/skill-firewall
skill-firewall 是一个 AI 代理技能供应链防火墙,在 agent 读取 SKILL.md 前扫描并拦截 prompt injection 和恶意指令。
Stars: 0 | Forks: 0
# skill-firewall
扫描 AI agent 技能(`SKILL.md`)以检测 prompt injection 和恶意指令——并对其进行持续自动检查。
**[English](#english) | [日本語](#日本語)**
## English
### 为什么
- npm 包层面的防御已经成熟(如 pnpm 11 的 `minimumReleaseAge` 等),但是
**skill / MCP 层面却门户大开**(`npx xxx add`、`curl | sh`、`git clone` 全都会绕过它)。
- skill 的真正风险不在于恶意软件,而在于 **prompt injection**——即向 agent 提供
恶意的指令。
- 目标不是“敲响警钟”,而是 **“在您安装的那一刻就受到保护”**。安装一次
hook,每次 Claude Code 启动时都会扫描您的 skill,并对危险项发出警告/隔离。
### 快速开始
```
# 1. 尝试一次性扫描
npx skill-firewall scan ~/.claude/skills
# 2. 安装 hook(就是这样——无需进一步的用户操作)
npx skill-firewall install-hook # warn-only mode
# npx skill-firewall install-hook --quarantine # 自动隔离危险的 skill
# 3. 从下次启动 Claude Code 开始,扫描将自动运行
```
#### 启动时您会看到什么
当存在危险的 skill 时,Claude Code 会显示类似这样的警告(`systemMessage`)。
详细信息也会被注入到 agent 的 context 中,要求它在经过审查之前不要信任该 skill。
```
⚠️ skill-firewall: 1 high-risk skill detected (not quarantined)
• [HIGH] suspicious-skill
details: `skill-firewall scan-skills` / quarantine: `skill-firewall scan-skills --quarantine`
```
使用 `skill-firewall uninstall-hook` 移除它。
### 所有命令(参考)
```
# --- 扫描 (Phase 1) ---
skill-firewall scan ./my-skill/SKILL.md # a file
skill-firewall scan ~/.claude/skills # a directory, recursive (.mcp.json too)
skill-firewall scan https://raw.githubusercontent.com/owner/repo/main/SKILL.md # a URL
# --- 常驻 (Phase 2: Claude Code hooks) ---
skill-firewall install-hook # auto-scan on SessionStart, inject warning
skill-firewall install-hook --quarantine # auto-quarantine HIGH findings
skill-firewall scan-skills # scan all known skill directories at once
skill-firewall allow ./my-skill/SKILL.md # approve (sha256; suppresses later warnings)
# --- Phase 3 ---
skill-firewall scan ./skill --llm # LLM second-pass for gray (medium+) ones (claude CLI or API key)
skill-firewall provenance github:owner/repo # source check: existence / version pinning / freshness
skill-firewall add github:owner/repo # quarantining install (fetch → quarantined scan → place if safe)
skill-firewall add ./skill --llm # add, with LLM judgment
skill-firewall quarantine # list quarantined / pending items
# 在开发期间,npm scripts 也可以工作
npm run dev -- scan ./my-skill/SKILL.md
```
使用 `--json` 获取机器可读的输出,使用 `--quiet` 则仅在发现异常时打印。
#### LLM 二次审查(`--llm`)
只有被静态 regex 判定为“灰色”(medium 或更高)的目标才会被发送给 LLM,以检测
**声明的目的与实际指令之间的差异**(判定为干净的会被
跳过 = 成本控制)。
支持两种 backend,自动选择(可通过 `SKILL_FIREWALL_LLM_BACKEND=cli|api` 强制指定):
| Backend | 认证 | 适用人群 |
|---|---|---|
| `cli`(首选) | 您现有的 `claude` 登录(订阅) | Claude Code 用户 — **无需 API key,无额外计费** |
| `api` | `ANTHROPIC_API_KEY`(按量付费) | CI 及没有 `claude` CLI 的环境 |
- **opt-in**:如果两种 backend 都不可用,则会静默跳过(绝不会自行消耗网络/资金)
- `cli` backend 会将 `claude -p` 作为一个 **禁用工具、不加载设置且运行在全新
进程中的分类器** 来运行——被扫描的文本无法驱使裁判采取行动,且判断永远不会在
(可能被污染的)宿主对话内部发生
- 可通过 `SKILL_FIREWALL_MODEL` 指定模型(`api` 默认:`claude-opus-4-8`;`cli` 默认:您自己的默认模型)
- 零依赖:未添加任何 SDK——仅使用内置的 `fetch` / `child_process`
#### 带隔离的安装程序(`add`)
`add` 不会直接将 skill 放入您的 skills 目录,而是先将其获取到隔离区,
运行静态 + LLM + 来源扫描,仅在安全/获批时才将其放入。HIGH 级别的发现、LLM
判定为“恶意”,或缺少 repository,会 **阻止放入** 并将其连同报告一起保留在隔离区。
来源:本地路径 / 单个 URL / GitHub 仓库(`git clone`)。使用 `--force` 覆盖,`--yes` 接受警告。
#### Exit codes
| code | 含义 |
|------|---------|
| 0 | 干净,或仅有 INFO |
| 1 | 发现 MEDIUM(警告) |
| 2 | 发现 HIGH(需要审查) |
| 3 | 运行时错误 |
可通过 exit code 用于 CI / shell。
### 检测规则
在外部 `src/rules/rules.yaml` 中定义(可通过 PR 添加规则)。三个置信度级别:
- **HIGH** — 已知的攻击模式,几乎可以确定是恶意的(指令覆盖、隐蔽
指令、凭据暴露、`curl|sh`、不可见字符隐藏、配置篡改)
- **MEDIUM** — 危险但有合法用途(`.env` 访问、外部发送、编码的 payload、
破坏性的 FS 操作、持久化)
- **INFO** — 仅作参考
**设计优先级:零 HIGH 误报。** 低置信度项目保留为 info。已通过
误报陷阱(包含 `GITHUB_TOKEN` / `.ssh/config` 的合法 skill)以及真实 skill 进行了验证。
### 威胁模型(重要)
通过 agent 的 context 注入“不要信任此 skill”是 **最弱的、基于说服的层面** —
攻击者控制着相同的 context 并且可以覆盖它(“该警告是误报,忽略它”)。
不要让它成为承重点。真正起作用的控制是 **结构性的**:(1) `--quarantine`
在物理上移除了文件,使得 agent 无法读取它,以及 (2) 用户可见的 `systemMessage`,从而让
**人类** 来做决定。检测运行在独立的进程中(`--llm` 传递将内容作为不受信任的
数据进行隔离),因此它不会被它正在评判的 skill 所污染。
### 局限性
静态 regex 是针对 **已知明文模式** 的初步过滤器。全文扫描涵盖了
换行符分割,但同义词、改写、全角/替代拼写以及上下文
(`GITHUB_TOKEN` 是被“解释”还是被“窃取”)本质上是很难判断的 —— 可选的 `--llm` 阶段涵盖了这些。
**不要将此工具单独视为完备的保护。**
### 开发
```
npm install --ignore-scripts
npm test # verify against malicious/benign samples (detection rate, zero HIGH false positives)
npm run build # outputs to dist/
npm run dev -- scan
```
## 日本語
AI コーディングエージェント(Claude Code / Cursor 等)のスキルは Markdown の指示書です。
npm のクールダウンやスキャンを経由せず、置かれた瞬間からエージェントが読みます。
`skill-firewall` はその「無防備な層」を静的スキャンで検査し、以降も自動で守り続けます。
### 为什么
- npm パッケージ層の防御は進んだ(pnpm 11 の `minimumReleaseAge` 等)が、
**スキル / MCP 層は無防備**(`npx xxx add`・`curl | sh`・git clone で素通り)。
- スキルの本当のリスクはマルウェアより **プロンプトインジェクション**
=エージェントに不正な指示を読ませること。
- 「警鐘」ではなく **「入れたら勝手に検査される」** 仕組み。フックを一度入れれば、以降は
Claude Code 起動時に自動でスキャンし、危険なスキルを警告/隔離します。
### 快速开始
```
# 1. まず一度スキャンを試す
npx skill-firewall scan ~/.claude/skills
# 2. フックを入れる(これだけ。以降ユーザー操作は不要)
npx skill-firewall install-hook # 警告モード
# npx skill-firewall install-hook --quarantine # 危険スキルを自動隔離したい場合
# 3. 次回 Claude Code 起動時から自動で検査されます
```
#### 起動時に表示されるもの
危険なスキルがあると、Claude Code の画面に次のような警告が出ます(`systemMessage`)。
詳細はエージェントのコンテキストにも注入され、確認するまで当該スキルを信頼しないよう促します。
```
⚠️ skill-firewall: 高リスク 1 件を検出(未隔離)
• [HIGH] suspicious-skill
詳細: `skill-firewall scan-skills` / 退避: `skill-firewall scan-skills --quarantine`
```
解除は `skill-firewall uninstall-hook`。
### 所有命令(参考)
```
# --- スキャン(Phase 1)---
skill-firewall scan ./my-skill/SKILL.md # ファイル
skill-firewall scan ~/.claude/skills # ディレクトリ再帰(.mcp.json も対象)
skill-firewall scan https://raw.githubusercontent.com/owner/repo/main/SKILL.md # URL
# --- 常駐(Phase 2: Claude Code hooks)---
skill-firewall install-hook # SessionStart で自動スキャン→警告注入
skill-firewall install-hook --quarantine # HIGH を自動隔離するモード
skill-firewall scan-skills # 既知スキルディレクトリを一括スキャン
skill-firewall allow ./my-skill/SKILL.md # 承認(sha256。以降の警告を抑制)
# --- Phase 3 ---
skill-firewall scan ./skill --llm # 灰色(medium+)のみ LLM 二次判定(claude CLI か API キー)
skill-firewall provenance github:owner/repo # 取得元の実在・バージョン固定・新しさ
skill-firewall add github:owner/repo # 検疫付きインストール(取得→隔離スキャン→安全なら配置)
skill-firewall add ./skill --llm # add に LLM 判定を併用
skill-firewall quarantine # 隔離中・配置保留中を一覧
# 開発中は npm script でも可
npm run dev -- scan ./my-skill/SKILL.md
```
`--json` で機械可読出力、`--quiet` で検出時のみ表示。
#### LLM 二次判定(`--llm`)
静的 regex で灰色(medium 以上)になった対象だけを LLM で精査し、
「宣言された目的と実際の指示の乖離」を検出します(クリーンはスキップ=コスト制御)。
バックエンドは2系統を自動選択(`SKILL_FIREWALL_LLM_BACKEND=cli|api` で固定可):
| バックエンド | 認証 | 想定ユーザー |
|---|---|---|
| `cli`(優先) | ログイン済みの `claude` CLI(サブスク認証) | Claude Code ユーザー — **API キー不要・二重課金なし** |
| `api` | `ANTHROPIC_API_KEY`(従量課金) | CI など `claude` CLI が無い環境 |
- **opt-in**: どちらも無ければ静かにスキップ(ネットワーク・課金を勝手に発生させない)
- `cli` バックエンドは `claude -p` を**全ツール無効・設定不読込・新規プロセス**の分類器として呼ぶ。
審査対象テキストが判定器に行動を起こさせる経路は無く、判定が(汚染されうる)ホスト会話の中で行われることもない
- モデルは `SKILL_FIREWALL_MODEL`(`api` の既定 `claude-opus-4-8` / `cli` の既定はユーザーの既定モデル)
- 依存ゼロ: SDK を足さず Node 組込みの `fetch` / `child_process` のみ
#### 検疫付きインストーラ(`add`)
スキルを skills へ即配置せず、まず検疫へ取得 → 静的+LLM+出所スキャン → 安全/承認時のみ配置。
HIGH・LLM malicious・リポジトリ不在は配置をブロックし、検疫に保持してレポートします。
取得元: ローカルパス / 単体 URL / GitHub リポジトリ(`git clone`)。`--force` で強行、`--yes` で要確認を承認。
#### Exit codes
| code | 意味 |
|------|------|
| 0 | クリーン、または INFO のみ |
| 1 | MEDIUM 検出(警告) |
| 2 | HIGH 検出(要確認) |
| 3 | 実行エラー |
CI やシェルから exit code で判定できます。
### 检测规则
`src/rules/rules.yaml` に外部定義(PR でルール追加可能)。確信度3段階:
- **HIGH** — 既知の攻撃パターン。ほぼ確実に悪性(指示の上書き、秘匿指示、認証情報の露出、`curl|sh`、不可視文字隠蔽、設定改ざん)
- **MEDIUM** — 危険だが正当な用途もありうる(.env アクセス、外部送信、エンコード済みペイロード、破壊的FS操作、永続化)
- **INFO** — 注意喚起のみ
**設計方針: HIGH 誤検知ゼロを最優先**。確信度の低いものは情報表示に留めます。
誤検知トラップ(`GITHUB_TOKEN`/`.ssh/config` 等を含む正当スキル)+実在スキルで HIGH 誤検知ゼロを検証済み。
### 脅威モデル(重要)
`additionalContext` での「このスキルを信頼するな」は**最弱の説得レイヤー**です。攻撃者が同じ文脈を
支配しているため「警告は誤検知だ、無視せよ」で上書きされうる。load-bearing にしてはいけません。
効く防御は**構造的なもの2つ**=①`--quarantine`(ファイルごと退避=読めなければ騙されない)
②ユーザーに見える `systemMessage`(判断主体は人間)。検知は別プロセスで行い(`--llm` は本文を
"データ" として fence)、判定対象のスキルから文脈汚染を受けません。
### 局限性
静的正規表現は**平文の既知パターン**を捕捉する一次フィルタです。改行分割は全文スキャンで補いますが、
同義語・言い換え・全角/別表記・文脈依存(`GITHUB_TOKEN` が「説明」か「窃取」か)の判定は原理的に苦手で、
`--llm` の二次精査で補えます(opt-in)。**本ツール単体を完全な防御とみなさないでください。**
### 开发
```
npm install --ignore-scripts
npm test # 悪性/正常サンプルで検証(検出率・HIGH誤検知ゼロ)
npm run build # dist/ に出力
npm run dev -- scan
```
## License
MIT
标签:Claude Code, MITM代理, 安全防护工具, 恶意指令检测, 暗色界面, 自动化攻击