はじめに
前回・前々回の記事でX(旧Twitter)とQiitaのMCPサーバーを作りました
開発にはClaude Codeのスキルを活用していて
他の方が公開しているスキルもいくつかインストールして使っています
で、次は何作ろうかなと考えていたときに
ふと思ったことがあります
「Skill に Kill される」
自分はエンジニアなのである程度コードを読んだり
発信者の信頼度等を見てからスキルなりMCPサーバは入れます
eval が見えたら身構えるし、
環境変数を外部に送っていたら気づく
ただこれ、非エンジニアの方が同じことをできるかというと厳しいなと。
「このスキル便利そう!」でインストールした先に何が待っているか
想像するだけでちょっと背筋が寒くなりました
AIエージェントのサプライチェーン攻撃はもう現実になっている
直接的な論証ではないかもしれませんが
スキルの「可能性」と「脆弱性」の
両面を持っていることがよくわかる例として
最近話題のAI版ダークウェブこと「OpenClaw」
スキルマーケットプレイス「ClawHub」では
全スキルの約12%が悪意あるスキルだったことが発覚しているようです
もちろん、これはスキルやMCPだけ問題ではなく
OpenCrawの特性による部分も多く影響していますが
スキルを8個インストールしたら1個はマルウェアを引ける
という状況があるということは事実です
いずれの記事も非常に興味深い内容です
手口はシンプルで恐ろしい
「便利そうなスキル」を公開して、インストール手順の中に悪意あるファイルのダウンロードを仕込む
ユーザーは「前提条件です」と言われたら素直に実行してしまう
その結果、暗号資産のウォレット秘密鍵やSSH認証情報が盗まれていたわけです
AIエージェントはシェルコマンド実行・ファイル読み書き・スクリプト実行が可能です
つまり、悪意あるコードが入り込めばroot権限に近いアクセスを許すことになります
作る側だからこそわかる「自由度」の怖さ
MCPやスキルを作る側をやっていると
「スキルにどれだけ自由度があるか」が肌感覚でわかります
SKILL.mdに書かれた指示はClaudeが実行する可能性がある
シェルコマンドやスクリプトの実行指示が入っていれば、それもまた忠実に実行される
Claudeはとても素直ないい子なので
「このスクリプトを実行してください」と書かれていれば疑わずに実行します
私のようなアマノジャク人間だったら「え、なんで?」と聞き返すかもしれないところを
AIは 指示通りに動くことが仕事 なので、巧妙に隠された悪意ある指示にも従ってしまう
人もAIも素直さは強さであり弱さですね
既存のセキュリティチェックスキルを調べた
同じ問題意識を持っている人はすでにいて
スキルやMCPサーバーの安全性を検証するためのスキルがいくつか公開されていました
もちろんこれもスキルなので前述の危険がある可能性自体は抱えていますが
安全であることが確認できたものを入れれば
スキルにキルされる可能性を下げる助けになることは間違いありません
中身を見てみるとどちらもよくできていて非常に勉強になります
正規表現ベースのスキャナーや多言語バイパス検出、Unicode攻撃の検知など
網羅的なチェックが実装されていて、先人に感謝です
ただ、両方に共通する特徴がひとつありました
スキル自体にPythonやBashのスクリプトが含まれている
セキュリティツールにコードが入っている問題
ここで少し立ち止まります
スキルにスクリプトが入っているということは
そのスキル自体がPCのプロセスを使って動くということです
セキュリティを検証するためのツールが、検証対象と同じ攻撃面を持っている
耐震診断の業者が、診断のために壁に穴を開けるようなものです。
いや信頼してますけど、構造的にどうなんだという話
そしてもうひとつ
正規表現やロジックで検出するアプローチは既知のパターンには強い
でも見たことのないパターンには弱い
攻撃者がパターンを少し変えれば素通りしてしまう
しかもregexは毎回まったく同じものを見逃す
再現性が高いのは一見メリットですが
偽陰性(見逃し)が再現性高く繰り返されるのは、セキュリティとしては疑問が残ります
コードを含まないスキルを作ってみようか
そこで、逆のアプローチを取ることにしました
スクリプトなし。コードなし。マークダウンだけ。
スキルの本質は「Claudeに手順的知識を渡すフォーマット」です
実行エンジンは Claude自身
だったらチェックリストと脅威パターンと判定基準をマークダウンで渡して
Claudeの推論させる方がいいのではと思いました
regexスキャナーはパターンマッチで検出する
Claudeは意図を推論して検出する
たとえば deploy.sh が .env を除外していない問題や
config.d.ts に allowUnrestrictedFileAccess というフラグがあるリスクは
チェックリストに明記されていなくてもClaudeなら文脈から気づけます
LLMは毎回微妙に違う観点で見るので複数回実行すれば網羅性が上がる
regexが「毎回同じものを見逃す」のとは対照的です
さらに、作成者の情報(アカウントの年齢、リポジトリのスター数)や
脅威パターンの組み合わせ(機密データアクセス × ネットワーク通信 = データ窃取の意図)も
マークダウンで判定基準を書いておけばClaudeが適用してくれます
これは生成AIだからこそできるアプローチです
そしてスキル自体が完全にマークダウンなので 攻撃面はゼロ
セキュリティツールが新たな攻撃ベクターになるという本末転倒は起きません
作ったもの
6ステップのワークフローで構成されています
いずれもスキル内の実装で実行せず
あくまでLLM自身が実行することを前提として設計しています
-
Author Verification —
gh apiでアカウント年齢・リポジトリシグナルを確認 - ファイル収集 — 対象のコードを全て読み込む
- リスク分類 — ファイルをCritical / High / Medium / Low に分類
- チェックリスト照合 — スキル用 / MCP用で分離されたチェックリストで検証
- クロスコリレーション — 単独では無害な所見の組み合わせで脅威を判定
- レポート出力 — SAFE / CAUTION / DANGER の3段階で結論
実際に使ってみた
実際の2つの監査結果を紹介します
Anthropic公式スキル — frontend-design
評価結果
| 項目 | 結果 |
|---|---|
| 対象 | anthropics/skills / frontend-design |
| Author Trust | Trusted(Anthropic、5年以上、72,243 stars) |
| Critical / Warning | なし |
| 判定 | SAFE |
概要
スクリプトなし、ネットワークアクセスなし、実行可能コードなしの純粋なマークダウンスキル。フロントエンド開発のためのデザインガイドラインと美的方向性のみを含む。コードレススキルパターンの模範的な実装。
SKILL.mdにデザインガイドラインしか含まれていない純粋なマークダウンスキルです
スクリプトなし、ネットワークアクセスなし、実行コードなし
攻撃面ゼロ — お手本のようなスキル
対象: anthropics/skills / frontend-design (スキル)
リスクレベル: SAFE
作者の信頼性
- 公開者: Anthropic
- アカウント年齢: 5年以上(2020年〜)
- シグナル: 72,243 stars, 7,394 forks, 27,351 followers
- 評価: 信頼(既知の公開者)
概要
スクリプトなし、ネットワークアクセスなし、実行可能コードなしの純粋なマークダウンスキル。フロントエンド開発のためのデザインガイドラインと美的方向性のみを含む。コードレススキルパターンの模範的な実装。
検出結果
Critical(即座の脅威)
- なし
Warning(潜在的リスク)
- なし
Info(備考)
-
SKILL.mdにはデザインガイドラインと美的指示のみ — 実行コード、シェルコマンド、外部参照なし。 - スクリプト、リファレンス、静的フォント以外のアセットなし。
- 攻撃面ゼロ。
推奨
[x] 安全にインストール可能
自作 X-Twitter-MCP
次に自分が作ったMCPの評価をしてもらいましょう
評価結果
| 項目 | 結果 |
|---|---|
| 対象 | sunu-py-jp/X-Twitter-MCP |
| Author Trust | Low(アカウント1ヶ月未満、0 stars、0 followers) |
| Warning | 4件(API認証情報の読み取り、DM送信、投稿機能、低いauthor trust) |
| 判定 | CAUTION |
対象: sunu-py-jp/X-Twitter-MCP (MCP サーバー)
リスクレベル: CAUTION
作者の信頼性
- 公開者: sunu-py-jp
- アカウント年齢: 1ヶ月未満(2026年2月〜)
- シグナル: 0 stars, 0 forks, 0 followers, MIT license
- 評価: 低信頼(新規アカウント、コミュニティシグナルなし)
概要
Twitter/X API v2 へのフルアクセスを提供する TypeScript MCP サーバー。公式 twitter-api-v2 ライブラリを使用したクリーンな実装で、Zod スキーマによる適切な入力バリデーションを備える。悪意あるパターンは検出されなかったが、強力な機能(ツイート投稿、DM 送信、フォロー管理)を持つため慎重な設定が必要。
検出結果
Critical
- なし
Warning
-
src/client.ts:9-13— 環境変数から4つの API 認証情報を読み取り(X_API_KEY,X_API_SECRET,X_ACCESS_TOKEN,X_ACCESS_TOKEN_SECRET)。意図通り Twitter API に送信されるが、認証情報の権限範囲に注意が必要。 -
src/tools/dm.ts:7-28—send_dmツールは任意のユーザーに DM を送信可能。信頼されていないクライアントからアクセスされた場合に悪用の可能性がある強力な機能。 -
src/tools/tweets.ts:6-31—post_tweetツールは認証済みアカウントでツイートを投稿可能。この書き込み機能に注意が必要。 - 作者の信頼性が低い(コミュニティシグナルのない新規アカウント)。上記の検出結果との相互相関により全体的な注意レベルが上昇。
Info
- クライアント・サーバー・ツールが明確に分離された、構造の良いコードベース。
-
src/server.ts:36-51—X_ENABLED_GROUPSとX_DISABLED_TOOLS環境変数でツールアクセスを細かく制御可能。優れたセキュリティ設計。 - すべてのツール入力に Zod スキーマによる入力バリデーション。
- 依存関係は最小限で著名なもののみ(
@modelcontextprotocol/sdk,twitter-api-v2,zod)。 -
eval,exec,child_process、難読化コード、データ流出パターンは検出されず。
推奨
[x] 注意してインストール — 書き込みアクセスが明示的に必要でない限り、X_ENABLED_GROUPS で読み取り専用ツール(例: tweets:get,timelines:get)に制限すること。API トークンの権限を確認すること。
自分で作ったものにCAUTIONを出されました
おい!!!
といいたいところですが
残念ですが、これは非常に正しい判定です
アカウントが新しくてコミュニティシグナルがない以上、第三者から見れば信頼性は低い
「DM送信ができる」「投稿ができる」という機能は正当な目的ですが
AIにその権限を与えるのはたしかにリスクがある
他の監査例(shell実行系MCP、ファイルシステムMCP、大規模スキルコレクション)は
EXAMPLES.md にまとめています
参照しているリポジトリはランダムに選定したものです
評価がCAUTIONとなっているものもありますが
どれも悪意はなく非常に素晴らしいものです
企業がAIを導入しづらい理由のひとつ
ここまで個人開発者の視点で書いてきましたが
この問題はもっと大きな文脈に繋がっています
ある程度成熟した企業がAIエージェントの導入に慎重なのは
「生成AIの精度が不安」という話だけではなく
サプライチェーンのセキュリティを担保できないからでもあります
npmやPyPIですら悪意あるパッケージの問題が絶えないのに
AIエージェントのスキル/プラグインのエコシステムはまだ黎明期です
信頼できるマーケットプレイスも、LLMの行動規範を縛るガバナンスもまだ整っていない
インストール前のセキュリティチェックを強制したり
組織単位で管理・制御する基盤 が整い始める年になるといいなと思っています
自衛するほどの知識がない場合もそうですが
自分とAIのダブルチェックをしていくことも重要です
この記事が役に立ったら、いいねとストックをお願いします
あとがき
今回のモチベーションは「スキルって便利だけど怖い」でした
趣味だったり作って継続して運用することに責任がかからない場合を除けば
作ることと守ること、両方やらないとダメで
それができる人をエンジニアと呼ぶんだろうと改めて記事を書きながら考えてました