
MCPセキュリティチェックリスト:安全なMCPサーバーデプロイのためのOWASP最小要件
OWASP GenAIセキュリティプロジェクトは、安全なMCPサーバーデプロイのための5つのカテゴリからなる最小要件を定義しています。本番環境への移行前に、アイデンティティ、分離、ツール、検証、デプロイメントの各領域における現在の態勢を評価するために、このチェックリストをご活用ください。...

認証はリモートMCPサーバーにとって最も重要なセキュリティ層です。OIDCを伴うOAuth 2.1がなぜ必須なのか、トークン委譲がどのように混乱した代理人攻撃を防ぐのか、そしてなぜトークンパススルーがAI統合における最も危険なパターンの一つなのかを学びましょう。
認証は、MCPサーバーの強力な機能が正規のユーザーに利用可能か、それとも攻撃者に利用可能かを決定するゲートキーパーです。これを誤ると、他のすべてのセキュリティ制御が無関係になります。メール、ファイル、データベースへのアクセスを持つ認証されていない、または不十分に認証されたMCPサーバーは、他のすべてを十分に堅牢化していても、重大な脆弱性となります。
OWASP GenAIセキュリティプロジェクトのガイドは、認証と認可をMCPサーバーの8つのコアセキュリティドメインの1つとして識別しており、ほとんどの開発者がデフォルトで実装するものを超える特定の要件があります。この投稿では、それらの要件がなぜ存在するのか、そしてそれらを正しく実装する方法を説明します。
MCPサーバーは、複数のプリンシパル間を仲介するため、従来のサービスよりも複雑な認証環境に直面します:
これらの関係のそれぞれには、独自の認証と認可制御が必要です。どのリンクの弱点も、他のものをバイパスするために悪用される可能性があります。
リモートMCPサーバー(ローカルのSTDIOやUnixソケットではなく、ネットワーク経由でアクセスされるもの)に対して、OWASP GenAIガイドは明確です:OIDCを伴うOAuth 2.1は必須であり、オプションではありません。
この要件が存在する理由は:
OAuth 2.1は明示的なスコープ制御を提供します。 すべてのアクセストークンは、どのリソースとアクションを認可するかを正確に宣言します。MCPサーバーは、ツール呼び出し時に、提示されたトークンがそのアクションに必要な特定のスコープを持っているかどうかを検証できます。ユーザーが認証されているだけでなく、この特定の操作に対して認可されているかどうかを確認します。
OIDCは暗号化されたアイデンティティを提供します。 OpenID Connectは、MCPサーバーがアイデンティティプロバイダーへのラウンドトリップなしで検証できるアイデンティティアサーション(IDトークン)を追加します。サーバーは、すべてのリクエストでiss(発行者)、aud(オーディエンス)、exp(有効期限)、および署名を検証します。
OAuth 2.1トークンは設計上短命です。 最新のOAuth仕様(OAuth 2.0のベストプラクティスを統合し置き換えるもの)は、定期的に更新する必要がある短命アクセストークンを強調しています。これにより、トークンが侵害された場合のダメージウィンドウが制限されます。
セッション確立時のみトークンを検証しないでください。すべてのツール呼び出しで検証します:
def validate_token(token: str, required_scope: str) -> TokenClaims:
claims = jwt.decode(
token,
key=get_public_key(claims_preview['kid']),
algorithms=["RS256", "ES256"]
)
assert claims['iss'] == EXPECTED_ISSUER
assert EXPECTED_AUDIENCE in claims['aud']
assert claims['exp'] > time.time()
assert required_scope in claims['scope'].split()
return claims
リクエスト間で検証結果をキャッシュしないでください。セッション開始時に有効だったトークンが、セッション中に取り消される可能性があります。
MCPクライアントが頻繁に変更される環境(例:異なるAIアシスタントが同じサーバーに接続する)では、静的APIキーや事前共有シークレットは不十分です。OAuth 2.1またはOIDCを使用した動的クライアント登録を使用して、接続時にクライアントのアイデンティティを検証します。特定のクライアントとサーバー間の既知の静的な関係には、許可リスト、ハードコードされた接続ポリシー、または相互TLS(mTLS)が適切です。
混乱した代理人は、MCPアーキテクチャにおいて特に危険な形で現れる古典的な認可脆弱性です。この攻撃は、MCPサーバーが誰の権限で行動しているかの曖昧さを悪用します。
このシナリオを考えてみましょう:
Aliceがアシスタントに「私のプロジェクトフォルダを要約して」と尋ねると、サーバーはAliceのトークンを使用して彼女のファイルにアクセスします — これは正しい動作です。しかし、攻撃者がサーバーを騙して独自のサービス資格情報を使用してリクエストを行わせた場合(おそらくツールポイズニング攻撃や間接的なプロンプトインジェクションを通じて)、サーバーの昇格された権限を使用して、Aliceが見る権限を持たないファイルにアクセスします。
サーバーは「混乱した代理人」です — その権限を持たない誰かの代わりにその権限を使用するように騙され、権限昇格のプロキシとして機能しています。
多くのMCP実装は、簡単のためにクライアントのトークンを下流のAPIに転送します。これは直感的に見えます — ユーザーのトークンはユーザーの権限を表しているため、すべての下流呼び出しにそれを使用することで、正しいアクセス制御が維持されます。
問題:MCPサーバーを信頼された仲介者として認識する下流APIは、転送されたユーザートークンのレベルではなく、サーバーのアイデンティティレベルを使用してリクエストを許可する可能性があります。そして、MCPサーバーが独自のイニシアチブで行動する場合(ユーザーが明示的に要求しなかったAI意思決定を通じて)、ユーザーのトークンではなく独自の資格情報を使用する可能性があります。
ユーザートークンの転送は、以下のことも行います:
クライアントトークンを転送する代わりに、MCPサーバーはOAuthの**On-Behalf-Of(OBO)**フローを使用して、下流サービスアクセス用の独自のトークンを取得する必要があります:
ユーザーがMCPクライアントに認証 → クライアントがユーザーアクセストークンを取得
MCPクライアントがMCPサーバーにユーザートークンを提示
MCPサーバーがOBOフローを介してユーザートークンをサーバートークンと交換:
POST /token
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
assertion=<user_access_token>
scope=<minimum_required_scope>
MCPサーバーが下流呼び出しに独自のOBOトークンを使用
OBOトークン:
OWASP GenAIガイドは、特定の推奨事項を示しています:時間単位ではなく分単位で測定される有効期間を持つアクセストークンを発行します。 これは、MCPサーバーがクライアントから受け入れるトークンと、下流サービスアクセスのために取得するトークンの両方に適用されます。
盗まれたアクセストークンは、正規のユーザーがログアウトしたか、パスワードを変更したか、セッションを取り消したかに関係なく、その完全な有効期間の間有効です。セッションの開始時に盗まれた24時間トークンは、攻撃者に24時間の永続的なアクセスを与えます。セッション中に盗まれた5分間のトークンは、最大5分間を与えます。
短命トークンは、定期的な再認証イベントも強制し、以下の機会を提供します:
各トークンは、実行される特定の操作に必要なスコープのみを保持する必要があります。現在のツール呼び出しがread:filesのみを必要とする場合、read:files write:files delete:filesスコープを持つトークンを発行しないでください。これにより、トークンが傍受された場合やモデルが予期しないツール呼び出しに操作された場合のダメージが制限されます。
def get_tool_token(user_id: str, tool_name: str) -> str:
# ツールを最小限必要なスコープにマッピング
required_scopes = TOOL_SCOPE_MAP[tool_name]
return oauth_client.get_token(
subject=user_id,
scopes=required_scopes,
lifetime_seconds=300 # 5分の有効期間
)
よくある間違いは、セッションIDを認可プロキシとして使用することです:リクエストが有効なセッションIDを持っている場合、サーバーはそれが認可されていると仮定します。これは、状態管理とアイデンティティ検証を混同しています。
正しいモデル:セッションIDは会話の状態を管理します。認可は、OAuthトークンのクレームを検証することによって、すべてのリクエストで独立して検証されます。有効なセッションIDを持つリクエストであっても、ツール呼び出しが許可される前に、有効で期限切れでない、適切にスコープされたOAuthトークンを提示する必要があります。
これが重要な理由は、セッションIDは、暗号化整合性保証を持つOAuthトークンができない方法で盗まれたり、推測されたり、再生されたりする可能性があるためです。
個々のツールハンドラー全体に散在する認可チェックを実装するのではなく、OWASP GenAIガイドは、以下を行う集中化されたポリシーゲートウェイを推奨しています:
集中化により、ポリシーがすべてのツールとエージェント全体で一貫して適用されることが保証されます。ツール固有の認可チェックは、開発中に忘れられたりバイパスされたりする可能性があります。ゲートウェイチェックはできません。
リモートMCPサーバーの最小限の認証セキュリティバーは次のとおりです:
OAuth 2.1がリモートMCPサーバーに必要とされるのは、明示的なスコープ制御を伴う委譲認可、短命トークン、暗号化検証、および標準化されたアイデンティティアサーション(OIDCを介して)を提供するためです。APIキーやセッションクッキーのようなより単純な方法では、最小権限アクセスを実装するために必要なスコープの粒度が欠けており、暗号化されたアイデンティティ保証を提供せず、セッション終了時に細かく取り消すことが困難です。
混乱した代理人とは、MCPサーバーが自身の(より高い)権限を使用して、リクエストしているユーザーが実行を許可されていないアクションを実行するように騙される権限昇格攻撃です。これは、トークンパススルーが使用される場合に発生します。サーバーがユーザーのトークンを下流のAPIに転送すると、サーバーの信頼されたステータスに基づいて、ユーザーが持つべきでないアクセスを許可される可能性があります。修正方法は、MCPサーバーの特定のアクセススコープに対して明示的に発行されたトークンを使用するOn-Behalf-Ofトークンフローを使用することです。
トークンパススルーとは、MCPサーバーが独自のサーバー発行資格情報を使用するのではなく、クライアントの認証トークンを下流のAPIに直接転送することを意味します。これが危険な理由は:(1)監査証跡を壊す — 下流システムはMCPサーバーではなくユーザートークンを見るため、サーバーへのアクションの帰属が不可能になる、(2)MCPサーバー独自のアクセスポリシーをバイパスする、(3)下流APIがユーザーのアイデンティティよりもMCPサーバーのアイデンティティを信頼する場合、混乱した代理人の脆弱性を作り出す、(4)MCPサーバーが侵害された場合、攻撃者は接続されているすべての下流サービスに対して転送されたユーザートークンへのアクセスを獲得する、からです。
OWASP GenAIガイドは、時間や日単位ではなく、分単位で測定される有効期間を持つトークンを推奨しています。トークンの有効期間が短いほど、トークンが盗まれた場合やセッションがハイジャックされた場合の悪用ウィンドウが制限されます。すべてのツール呼び出しは、セッション開始時のキャッシュされた検証に依存するのではなく、トークンの署名、オーディエンス、および有効期限を再検証する必要があります。
アルシアはFlowHuntのAIワークフローエンジニアです。コンピュータサイエンスのバックグラウンドとAIへの情熱を持ち、AIツールを日常業務に統合して効率的なワークフローを作り出し、生産性と創造性を高めることを専門としています。

当社のセキュリティチームは、MCP認証設定、トークン処理、認可フローをOWASP GenAI標準に照らして評価します。攻撃者よりも先にギャップを特定しましょう。

OWASP GenAIセキュリティプロジェクトは、安全なMCPサーバーデプロイのための5つのカテゴリからなる最小要件を定義しています。本番環境への移行前に、アイデンティティ、分離、ツール、検証、デプロイメントの各領域における現在の態勢を評価するために、このチェックリストをご活用ください。...

MCPサーバーは、従来のAPIリスクとAI固有の脅威を組み合わせた独自の攻撃対象領域を露出します。OWASP GenAIが特定した6つの重要な脆弱性(ツールポイズニング、ラグプル、コードインジェクション、認証情報の漏洩、過剰な権限、不十分な分離)について学びましょう。...

認証可能なMCPサーバーは、リモートアテステーションと機密コンピューティングをFlowHuntワークフローに導入し、AIエージェントやクライアントが接続前にサーバーの完全性を検証できるようにします。ハードウェアによる暗号学的証明を活用し、安全で改ざんされていないAIパイプラインを保証します。...