PaPoo
cover

MCP Gatewayの“便利さ”がそのまま危険になる話を、Quarkusの視点で読む

この記事のキーポイント

MCP、つまり Model Context Protocol は、AIエージェントが外部ツールや社内データにつながるための共通ルールとして注目されている。元記事は、その最新版に入った変更が「便利さ」と引き換えに新しい危険も持ち込んだ、とかなりはっきり警告している。ここが面白い。新機能の話なのに、テンションはかなり防御寄りだ。しかも大げさではなく、実装者が本当に気をつけないといけないタイプの話だと思う。

ポイントは、MCPが stateful な接続から、stateless な HTTP に寄ったことだ。stateless というのは、ひとつひとつのリクエストが単独で完結する方式のこと。見た目はシンプルだし、負荷分散もしやすい。けれどそのぶん、認証や整合性チェックを「毎回ちゃんとやる」責任がアプリ側に強く乗ってくる。便利になったぶん、守る場所が増えたわけだ。

記事が挙げている危険は大きく3つある。

ひとつ目は、header と body の内容がズレることで起きる protocol confusion だ。MCPでは x-mcp-header のような仕組みで、tool の引数を HTTP header にマッピングできる。これ自体はルーティングや連携には便利なのだけど、攻撃者が header 側を細工して、JSON-RPC 本文とは別の意味を持たせると危ない。たとえば、認可の判断は header を見ているのに、実際の実行内容は body に別の命令が入っている、というズレが起きうる。こういうのは本当に嫌なバグだ。気づきにくいのに、起きたら被害は派手になりやすい。

ふたつ目は、_meta を使った metadata injection だ。_meta は、stateless セッションや tracing、カスタムな client context を支えるための自由な入れ物として使われる。けれど、ここを信用しすぎると危ない。ルーティングに使ったり、SQL の組み立てに混ぜたり、ログにそのまま出したりすると、注入攻撃やログ汚染、場合によっては RCE につながる、と記事は指摘している。個人的には、こういう「便利なメタデータ置き場」はだいたい後から怖くなる、という印象がある。最初は単なる補助情報のつもりでも、気づくと重要な分岐に使われてしまうからだ。

三つ目は、​prompt manipulation を通じた権限のすり抜けだ。LLM は prompt injection に弱い。つまり、攻撃者が会話や入力を操作して、LLM に変なツール呼び出しをさせることがある。すると、LLM は人間の代わりに、しかもサービスアカウントの権限で動いてしまう可能性がある。ここで大事なのは、「AI が悪い」という話ではなく、「AI はだまされる前提で設計しないといけない」ということだと思う。AI を信頼しすぎると、最終的な実行権限まで持っていかれる。

記事の防御策は、かなり地に足がついている。派手な AI セキュリティ製品の話ではなく、Java アプリケーションの入口で何をするか、に集中している。

image_0003.svg

まずは Bean Validation を使って入力を厳しく縛る、という考え方だ。Bean Validation は、Java で値の形式や長さをチェックする仕組みで、@NotNull@Size@Pattern のような注釈を DTO に付ける。記事の例では、customer ID を CUST-1234 のような形式に限定し、traceContext も長さと文字種を絞っている。こうしておくと、SQL injection っぽい文字列や、変なパス文字列が、ビジネスロジックに届く前に止まる。地味だけど、こういう地味さが強い。セキュリティは結局、こういう「通さない」設計の積み重ねだ。

次に、​Reactive filter で header と body の整合性を確認する。Quarkus は reactive な設計なので、リクエストを非同期・非ブロッキングでさばきながら、入口で検査しやすい。記事では ContainerRequestFilter を使って、Mcp-Name header と JSON-RPC の method が一致しているかを見ている。合っていなければ 400 Bad Request で落とす。これはかなり筋がいい。認可をアプリの奥に置くのではなく、「境界」で止める発想だからだ。

Quarkus がここで推されている理由もわかりやすい。​build-time validation、つまりビルド時に多くを確定させる設計は、実行時にあれこれ曖昧なまま進まない。Enterprise security integrations も含めて、Java の堅実さと相性がいい。AI 時代になると、どうしても「新しい何か」に目が行きがちだけど、実際に守るのは昔ながらの入力検証と境界防御だったりする。このギャップはちょっと皮肉だけど、かなり現実的だ。

この記事を読んでいて印象に残るのは、MCP を「便利な接続規格」として持ち上げるだけで終わらず、その裏側の危険をちゃんと描いているところだ。特に、_meta と header mapping のような、いかにも実装者が「これ便利だな」と思いそうな機能ほど危ない、という指摘は鋭い。新しいプロトコルでは、悪意ある入力がどこから来るかを一段深く考えないといけない。AI の入力は、もう単なるフォーム入力ではない。会話であり、命令であり、時に攻撃の踏み台でもある。

個人的には、この記事のメッセージはかなりシンプルだと思う。MCP は enterprise で使いやすくなった。でも、使いやすさはそのまま安全ではない。むしろ、HTTP ベースで広くつながるからこそ、入口での厳密な検査が必要になる。Quarkus はその実装先としてかなり自然に見える。Java の堅さを、AI ツールゲートウェイの防波堤にする、という発想はわりと好きだ。


参考: Hardening MCP Gateways: Mitigating July 28 Security Risks in Java Applications

同じ著者の記事