flawopen.com/Teardowns/cve-2026-77244-mcp-atlassian-http-auth-bypass
CVE-2026-77244:mcp-atlassianの未認証HTTPツールアクセス
CVE-2026-77244では、未認証の呼び出し元がコミュニティプロジェクトmcp-atlassianのHTTPツールハンドラーに到達でき、運用者の環境変数に設定されたJiraまたはConfluence資格情報が使われる可能性がありました。主な修正は0.22.0です。SSE利用者は別の関連トランスポート問題の修正を含む0.23.1以降が必要です。[1], [4], [5], [6]
受付では、スタッフ専用ドアを開ける前に来訪者のバッジを確認する必要があります。以前の手順では、バッジがないと受付係のマスターキーを貸していました。この問題では、検証済みのユーザーIDなしにHTTPリクエストがツールへ届き、ツールが運用者の共有Atlassian資格情報を使えるという2つの欠落が連鎖しました。修正は未認証HTTPリクエストを拒否し、資格情報のフォールバックを明示的な設定にします。[1], [3]
主要な概念と専門用語
MCPトランスポート- クライアントとサーバー間でModel Context Protocolリクエストを運ぶ通信経路です。このCVEはmcp-atlassianのHTTPトランスポートに関するもので、アドバイザリではstdioは対象外です。[1], [4]
グローバル資格情報フォールバック- リクエストに個別のユーザーIDがない場合、サーバー環境に設定されたJiraまたはConfluence資格情報を使うことです。リモートから到達可能なHTTPでは匿名リクエストが運用者としての操作になり得ます。[1], [4]
フレームワーク対応
根本原因の分析 (Root Cause)
GitHub Security Advisoryが説明するのはコミュニティプロジェクトmcp-atlassianの攻撃経路であり、Atlassian製品の脆弱性ではありません。0.22.0より前では、HTTPミドルウェアがユーザーIDのないリクエストをツールハンドラーへ通すことがありました。環境変数に運用者の資格情報が設定されていると、JiraFetcherまたはConfluenceFetcherがそのグローバル資格情報へフォールバックできました。アドバイザリは、空でない任意の文字列を受け入れる不透明トークン検証器についても記載していますが、これは呼び出し元の実際のIDを証明しません。認証境界ではリクエストIDと資格情報選択の両方を保護し、IDがない、または未検証のユーザーに運用者の特権資格情報を継承させてはいけません。0.22.0の修正は未認証のstreamable-HTTP MCP POSTにHTTP 401を返し、単一ユーザー環境でALLOW_GLOBAL_CRED_FALLBACK=trueを明示した場合を除いてHTTPコンテキストでグローバルフォールバックを拒否します。stdioの動作は変更されません。別のGHSA-5j8j-256g-vvp5はSSEパスの照合ミスを説明し、0.23.1で修正されました。これはCVE-2026-77244ではありません。SSE環境は0.23.1以降に更新し、CVEの0.22.0修正だけで別のアドバイザリも直ると考えないでください。アドバイザリは悪用を確認しておらず、この記事も実際の侵害を主張しません。 CVEアドバイザリは、この経路の認証、トークン検証、認可の各不備をCWE-287、CWE-303、CWE-862に分類しています。 このアドバイザリでは、報告者としてcrazydude123が記載されています。[1], [3], [4], [5], [6], [7], [9], [10]
ステップ・バイ・ステップの攻撃フロー
MCPのHTTPエンドポイントに到達できる
コミュニティ版mcp-atlassianをHTTPで稼働させ、未認証の相手がトランスポートに到達できる構成です。stdioのみの構成はこのCVEの影響経路外です。[1]
ソースコード比較:脆弱 vs 堅牢化
上流の制御フローを絞って表現したもので、関数全体の逐語的なコピーではありません。修正はトランスポート境界でHTTP 401を返し、HTTPコンテキストでグローバルfetcherを返す前にも確認を加えています。[1], [3], [4]
# 影響を受ける制御フローを簡略化した表現です。
async def handle_request(scope, ctx):
user_identity = scope.get("state", {}).get("user_atlassian_auth_type")
# HTTP 境界で ID の欠落を拒否していませんでした。
return await call_tool_handler(ctx, user_identity=user_identity)
def get_fetcher(user_identity, global_config):
if user_identity:
return fetcher_for_user(user_identity)
# 環境設定の運用者資格情報にフォールバックします。
return fetcher_from_config(global_config)
# 0.22.0 に統合された保護策を簡潔に示したものです。
async def handle_request(scope, ctx):
user_identity = scope.get("state", {}).get("user_atlassian_auth_type")
if is_mcp_http_post(scope) and not user_identity and not allow_global_fallback():
return http_401("Authentication required")
return await call_tool_handler(ctx, user_identity=user_identity)
def get_fetcher(user_identity, global_config, *, in_http_context):
if user_identity:
return fetcher_for_user(user_identity)
if in_http_context and not allow_global_fallback():
raise PermissionError("Refusing operator credentials for an unauthenticated HTTP request")
return fetcher_from_config(global_config)
エンジニアリング&システム堅牢化チェックリスト
- ✓CVE-2026-77244の修正として
mcp-atlassianを0.22.0未満から0.22.0以降へ更新します。--transport sseを使う場合は別のGHSA-5j8j-256g-vvp5のため0.23.1以降へ更新します。[1], [4], [5], [6] - ✓直接bind、コンテナポート、ingress、ロードバランサー、VPN、開発トンネルなど、すべてのHTTP公開経路を特定し、更新中はアクセスを制限します。[1]
- ✓複数ユーザーまたはリモート公開HTTPでは
ALLOW_GLOBAL_CRED_FALLBACKを未設定またはfalseにします。明確な境界を持つ単一ユーザー構成でのみ意図して有効にします。[1], [4] - ✓ツール実行前に実際のユーザーIDを要求・検証します。非空トークン、ネットワーク位置、プロキシヘッダーだけでは、明示的な検証なしにIDを証明できません。[1], [7]
- ✓IDがない場合にツールハンドラー実行前にHTTP 401となること、HTTP fetcherが明示許可なしに環境資格情報を拒否することを回帰テストで確認します。[3], [4]
- ✓streamable HTTPとSSEを別々にテストします。SSE経路の認証問題は別のアドバイザリであり、CVEの0.22.0修正だけでなく0.23.1で修正されています。[5], [6]
- ✓脆弱なインスタンスが信頼できない相手から到達可能だった場合、サービスアカウントによるJira/Confluence操作を監査し、露出の可能性があれば資格情報をローテーションします。[1]
参考資料
- GitHubセキュリティアドバイザリ GHSA-wrhw-j3f9-8vc6 — CVE-2026-77244
- CVE.orgレコード CVE-2026-77244
- 上流PR #1448とコミット f500f5b
- mcp-atlassian v0.22.0リリース
- 別個のSSEアドバイザリ GHSA-5j8j-256g-vvp5
- mcp-atlassian v0.23.1リリース(SSE認証修正)
- MITRE CWE-287: Improper Authentication
- ThreatFrontierの報道(2026年10月2日)
- MITRE CWE-303: Incorrect Implementation of Authentication Algorithm
- MITRE CWE-862: Missing Authorization