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代理, 安全防护工具, 恶意指令检测, 暗色界面, 自动化攻击