Artificial Intelligence (AI)
従来型のMCPサーバに潜むSQLインジェクション脆弱性がAIエージェントに及ぼす影響
AnthropicのSQLite MCPサーバから発見されたSQLインジェクション脆弱性について、保存済みプロンプトの改変や情報流出、業務フロー乗っ取りに至る過程や、その対策を解説します。
- サプライチェーンの脆弱性は、広範な影響を及ぼします。Anthropicの脆弱な「SQLite MCPサーバ」は、アーカイブ化されるまでに5千回以上もフォークされてきました。こうして構築された数千に及ぶAIエージェントの多くは、SQLインジェクションに脆弱なコードを未修正のまま受け継ぎ、現在も本番環境で稼働している可能性があります。
- 本脆弱性が悪用された場合、よく知られたSQLインジェクションの手口を介して「保存済みプロンプトインジェクション攻撃」が行われます。結果、攻撃者にAIエージェントを直接操作され、不正行為の被害に遭うリスクが著しく増大します。
- 本脆弱性は、ワークフロー内の暗黙的な信頼関係を悪用した権限昇格の手段を生み出します。AIエージェントは多くの場合、内部のデータベースやログ情報、キャッシュ済みレコードなどを安全なものと見なします。そのため攻撃者は、不正なプロンプトをAIシステム内に埋め込むことで、AIエージェントを介して高権限のツール(メール、データベース、クラウドAPI)を操作し、監視を回避しながら情報窃取や水平移動・内部活動に及ぶ可能性があります。
- 未修正のフォーク版を利用している企業や組織では、情報流出やサービス障害など、運用面と評判面双方でのリスクが懸念されます。現状、修正パッチの公開予定はないため、改修対応は開発側で行う必要があります。そのため本稿末尾では、有効な対策や推奨事項を記載しています。
はじめに
Trend™ Researchの調査により、AI企業「Anthropic社」が提供していたSQLite MCP(Model Context Protocol)サーバの参考実装から、単純ながらも危険なSQLインジェクション脆弱性が発見されました。これに該当するGitHubリポジトリは2025年5月29日時点でアーカイブ化されましたが、すでに5千回以上に渡って複製、フォークされてきました。留意点として、問題のコードは当初から本番利用を想定したものではなく、「参考実装」という位置付けで提供されていました。
当該の脆弱なコードが攻撃者に悪用された場合、未認可コマンドの実行や不正なプロンプトの投入、情報の窃取、AIエージェントが絡むワークフローの乗っ取りなど、さまざまな事態に発展する恐れがあります。本稿では、問題となった脆弱性の根本要因や想定される影響、有効な対策について解説します。
脆弱性の発生箇所
本脆弱性の主因は、ユーザ入力に対する検証が欠落していることにあります。問題のソースコードでは、ユーザ入力がサニタイジング(危険な埋め込みコードなどを無効化)されることなく、そのままSQL文の一部として付け加えられます。こうして組まれたSQL文は、後にPythonのドライバ「sqlite3」に引き渡され、フィルタリングやバリデーションなしで実行されます。図1のコードは、脆弱性の主因と見られる箇所であり、入力のパラメータ化といった対策がないために、SQLインジェクションのリスクを生み出しています。

上述の不備は、SQLインジェクションの発生条件を十分に満たすものです。攻撃者に悪用された場合、不正なクエリをシステムの内部に埋め込まれ、重大なセキュリティ事象に発展する可能性があります。
非営利団体「OWASP」が提示する「SQLインジェクションの防止ガイド(SQL Injection Prevention Cheat Sheet)」では、有効な対策の筆頭として、「パラメータ化クエリの使用」が十年以上に渡って挙げられています。これは、設計ベースでSQLインジェクションを防ぐための取り組みであり、データベース側で「コード」と「データ」を区別することが可能になります。本ベストプラクティスを怠り、代替の対策も取らなかった場合、認証回避や情報窃取、改ざん、さらにはSQLiteの仮想テーブル機能を介した任意のファイル書き込みなど、古典的なSQL攻撃の門戸が大きく開かれることになります。
単純なSQLインジェクションによって顧客サポート用のAIエージェントが乗っ取られる仕組み
今回の脆弱性がどのように悪用されるかについて、顧客サポート用AIエージェントを例に解説します。このAIエージェントは、顧客がWebフォームを通して送信したチケットを「SQLite MCPサーバ」から取得します。また、権限を持つサポートエンジニア(またはボット)が、「対応待ち状態(open)」の全チケットに対する仕分け作業を行います。想定される攻撃者は図2の通り、SQLite MCPサーバの脆弱性を悪用することで、SQLインジェクションのペイロードをAIエージェント側に送り込みます。

1. 攻撃者が問い合わせチケットを送信
図3は、攻撃者が問い合わせ用Webフォームの本文欄にSQLインジェクションのコードを埋め込んだ場合に、最終的に実行されるSQLクエリの全容を示します。想定仕様として、本文欄に記入した内容は、テーブル「support_tickets」のフィールド「body」に登録されます。通常であれば、図3に示す5行目の時点で、SQL文は完結します。しかし、今回の例では、攻撃者が本文欄に埋め込んだSQL(5〜11行目のハイライト箇所)により、最初のSQL文を途中で終了させて1件目のチケットを登録した上で、不正な「保存済みプロンプト」を含む2件目のチケットも併せて登録します。

図3:正常なチケット作成フローであれば、SQLは5行目で終了し、1件のチケットのみが登録される。しかし、攻撃のフローでは、脆弱性によって追加のSQL文(5~11行目のハイライト箇所)が実行され、2件目の不正なチケットも併せて登録される。
2. 脆弱なSQLite MCPサーバを通して不正なプロンプトが保存される
これは、XSS(クロスサイトスクリプティング)攻撃のLLM版であり、一般に「保存済みプロンプトインジェクション(Stored Prompt Injection)」と呼ばれ、LLM環境の筆頭リスクとして知られています。攻撃者は、SQLite MCPサーバの脆弱性を悪用し、エージェント経由で不正なプロンプトを「対応待ち状態(open)」で保存します。これにより、システムのバックエンド側で「確認待ち状態(pending)」のチケットに課せられるインジェクション対策や検証の手続きを回避します。
3. サポートエンジニアやボット機能が「対応待ち状態」のチケットに対する仕分け作業を実施する
「仕分け」の段階では、サポートエンジニアやボット機能がAIエージェントに指示を出し、不正なプロンプトの埋め込まれたチケットを正規なものと見なして読み込みます。
4. AIモデルがプロンプトの指示内容を実行する
LLM(大規模言語モデル)は、不正な保存済みプロンプトの指示内容に応えるため、高い権限で動くメールクライアントや、他のMCPサーバを含む内部ツールにアクセスする。今回の例では、顧客データ(customer.csv)を攻撃者のメールアドレス(attacker@evil.com)に送信する。
メール用のMCPツールは、高い権限で稼働します。また、仕分けのワークフローでは、「対応待ち状態(open)」のチケットが暗黙的に信頼されます。そのため、攻撃者は1件の不正な入力文を送りつけるだけで「保存済みプロンプトインジェクション」の手口を実現し、システム侵害や情報流出、水平移動・内部活動を行う可能性があります。
AIエージェントがMCPサーバを用いて情報を出し入れする環境では、一見ささいな SQLインジェクションのバグがもたらす影響の範囲は、データ層に留まりません。それは、保存済みプロンプトインジェクションの大きな足場を攻撃者に与えるものであり、AIエージェントの高い権限を濫用した不正行為や、情報窃取の自動実行、プラットフォーム間での水平移動・内部活動などを誘発します。
情報の開示と現在の状況
2025年6月11日にトレンドマイクロは、適切な情報開示のガイドラインに基づき、本件をAnthropic社に非公開で報告しました。これに対してAnthropic社からは、問題のリポジトリはアーカイブ済みの「参考実装」であるため、当該脆弱性は「対応範囲外」である旨の回答がありました。GitHub上の議論「#1348」によると、本稿執筆時点で、修正パッチの予定はないものと見られます。また、Anthropic社が公開していた参考実装は、全てアーカイブ化されています。
クイック修正・チェックリスト
アーカイブ化済みのリポジトリに関するオフィシャルな修正パッチは予定されていないため、本脆弱性の修正対応は、開発側に委ねられます。以降に、開発チーム側で用意したSQLite MCPサーバのフォーク版やデプロイメントから問題の脆弱性を特定し、対処するためのクイック修正・チェックリストを記載します。
1. 脆弱なSQLite MCPサーバを手動で修正するため、f文字列をプレースホルダに置き換える: AnthropicのSQLite MCPサーバを2025年5月29日以前にフォークしていた場合、またはアーカイブ版を利用している場合は、メソッド「_execute_query」の呼び出し箇所を全てチェックし、下記のように、パラメータ化に基づく実行方式を適用する。
# vulnerable
results = db._execute_query(arguments["query"])
# quick patch
sql, params = arguments["query"], tuple(arguments.get("params", []))
if";" in sql: # simple single-statement guard
raise ValueError("stacked queries blocked")
results = db._execute_query(sql, params) # Use parameterized input
2.「SELECT … FROM {table}」のようにテーブル名を動的に指定する場合は、ホワイトリストで許可されたテーブル名だけを利用できるように、制限をかける。
3. sqlite3の設定や制御を通し、複数ステートメントの同時実行を禁止する(isolation_level=Noneとすることで暗黙的な自動コミットは防げるが、依然として、入力の検証を行う必要がある)。
4. LLMとしての境界を逸脱した異常なプロンプトを監視する(例:生成されたSQLに予期せぬ「 SELECT * FROM users」が含まれている、または仕分けエージェントから大量のメールが突然送信される)。
まとめと推奨事項
今回の事例は、古くから知られている問題の再来と言えます。従来からの入力サニタイジングに関するバグがAIエージェントに潜んでいた場合、その影響はデータ層のみに留まりません。文字列に対するパラメータ化の適用漏れがMCPサーバ内に1件含まれていただけでも、それは何千ものフォークバージョンに伝播して私有のコードベースに入り込み、高権限の自動化ワークフローに適用されます。教科書的なSQLインジェクションの手口によって「保存済みプロンプトインジェクション」が実現するのであれば、フォークなどによって派生した全LLMが攻撃者の指示を受け入れる状態になり、顧客情報の窃取やメールの大量送信、隣接システムへの水平移動といった不正行為に利用される可能性があります。
本事例の教訓は、明白です。過去のWebアプリに潜むバグを現在のエージェント・インフラにまで引き継げば、それは攻撃者を大いに利することになり、1件のSQLインジェクションを皮切りにエージェント全体の侵害に至らせる可能性があります。こうしたセキュリティ欠陥を塞ぐためには、厳格なコーディングの標準化や、サプライチェーンの自動監視に加え、保存済みコンテンツの安全性を常に疑って検証するランタイム型のガードレールシステムが強く求められます。
今回のような脆弱性を防ぐ上では、先に述べたクリック修正・チェックリストの他に、以降のベストプラクティスが有効です。
- 「OWASP」による「SQLインジェクションの防止ガイド(SQL Injection Prevention Cheat Sheet)」を再確認する:先述のようにOWASPは、SQLインジェクションを防ぐ対策の筆頭として、「パラメータ化クエリの利用」を長期に渡って挙げている。これはセキュリティ習慣の基本であり、LLMやエージェント型システムを導入する場合は、特に注意する必要がある。
- AIエージェントのワークフロー内に、暗黙的な信頼に基づく動作や判断が含まれていないかをチェックする:内部データをデフォルトで安全なものと見なすワークフローは、「保存済みプロンプトインジェクション」に脆弱な可能性がある。ユーザ生成やシステム保存の入力について、AI側がそれをいつ、どのように読み取り、どのように処理するかについて、適宜レビューすることが望ましい。
- 高権限ツールへのアクセスを制限する:AIエージェントにメールやファイルシステム、外部AIへのアクセス権を無制限に開放することは、推奨されない。悪用を阻止するために、検証や承認の手続きを導入する。また、万一の場合にも影響を封じ込められるように、サンドボックス環境を整備する。
- 異常な動作を監視する:不審なプロンプトや想定外のSQLコマンドを監視する。また、標準的なワークフローから外れた形でエージェントがメールを外部送信するなど、正常時と異なるデータフローを検知するための体制を整える。
参考記事:
Why a Classic MCP Server Vulnerability Can Undermine Your Entire AI Agent
By: Sean Park
翻訳:清水 浩平(Platform Marketing, Trend Micro™ Research)