FlawOpen

flawopen.com/Teardowns/cve-2026-27826-mcp-atlassian-ssrf

● CVE-2026-27826 · CVSS 8.2[1], [3] · 高
セキュリティ研究 · FlawOpen

CVE-2026-27826:MCP AtlassianのSSRF

CVE-2026-27826 の当初のヘッダー経由 SSRF は 0.17.0 で修正されました。後続の別個の SSRF 脆弱性は 0.22.0 で修正されています。全環境の最低バージョンを決める前に各アドバイザリを確認してください。[1], [2], [6], [8], [9], [10], [11]

💡 わかりやすい解説 (ELI5)

会社の郵便室は、承認済みの事業所にだけ荷物を届ける決まりだとします。来訪者が専用用紙に別の宛先を書き、職員が確認せずに従ってしまいます。サーバー側のfetcherが郵便室に当たります。リクエストヘッダーが宛先を決め、サーバーが外向きリクエストを送信しました。0.17.0の修正では接続前に指定URLを検証し、リダイレクト先も確認します。運用者は追加で許可ドメイン一覧を設定できます。[1], [2]

主要な概念と専門用語

Server-side request forgery (SSRF)
呼び出し元がサーバーの外向きリクエストを操作し、アプリケーションが意図していない宛先へ到達させる脆弱性です。[1], [4]
MCPトランスポート
MCPクライアントとサーバー間の通信路です。この問題はstreamable-HTTPおよびSSEに影響し、アドバイザリで説明されたstdioのみの構成には影響しません。[1]
ヘッダー認証によるマルチテナント方式
リクエストごとにAtlassianのURLとトークンを受け取り、テナント専用のAPIクライアントを作る方式です。[1], [2]
送信先ネットワークポリシー
サービスが接続できる宛先を制限し、アプリケーションのURL検証不備による影響を抑えるネットワーク制御です。[12], [1]
間接的なプロンプトインジェクション
ツールが返す信頼できないコンテンツに、モデルへ影響を与える指示が含まれることがあります。このCVEでは攻撃者が制御する応答がツール結果に入る影響が説明されています。これはSSRF自体とは別の影響経路です。[1], [7]
後続の SSRF 修正
CVE-2026-27826 の当初のアドバイザリでは、修正版は 0.17.0 とされています。その後、メンテナーは別々の不完全な修正経路を CVE-2026-77242、CVE-2026-77267、CVE-2026-77249、CVE-2026-77274 として公開し、それぞれ 0.22.0 を修正版としています。これらは別の CVE であり、CVE-2026-27826 の影響範囲を拡大するものではありません。全環境の最低バージョンを決める前に、さらに新しいアドバイザリも確認してください。[8], [9], [10], [11]

フレームワーク対応

根本原因の分析 (Root Cause)

影響を受けるHTTP経路では、サーバーがリクエストからX-Atlassian-Jira-UrlまたはX-Atlassian-Confluence-Urlを取り出し、fetcher作成に使うJiraConfigまたはConfluenceConfigへ渡していました。脆弱なヘッダー認証分岐では、fetcherが最初のリクエストを送る前に、宛先をサーバー設定のテナントURLや宛先ポリシーと照合していませんでした。メンテナーのアドバイザリが根本原因として挙げているのはリクエストmiddlewareと依存関係プロバイダーであり、個別のMCPツールハンドラーではありません。影響には対象HTTPトランスポートとヘッダー認証条件が必要です。すべてのMCP構成に一般化しないでください。[1], [2]

ステップ・バイ・ステップの攻撃フロー

ステップ 1

到達可能なHTTPトランスポート

streamable-HTTPまたはSSEを使用し、MCPエンドポイントに到達できる呼び出し元へ公開しています。[1], [2]

ステップ 2

ヘッダーがサービスURLを選択

影響を受けるヘッダー認証経路では、JiraまたはConfluenceのURLとトークンがあり、別経路で想定されるAuthorizationヘッダーがありません。[1], [2]

ステップ 3

middlewareがfetcherを作成

middlewareが受信したURLを保存し、依存関係プロバイダーが想定された宛先境界を強制せずにAtlassian fetcherの設定に使用します。[1], [2]

ステップ 4

サーバーが外向きリクエストを送信

fetcher初期化時に呼び出し元が指定した宛先へリクエストが送られます。ネットワークや応答次第で内部サービスが露出したり、攻撃者が制御する内容がツール結果へ混入したりします。[1], [2]

ソースコード比較:脆弱 vs 堅牢化

脆弱なコード例では、リクエストヘッダーのURLがサーバーの外向き接続先を選びます。upstream の 0.17.0 パッチは、このヘッダー指定のテナント方式をサーバー側テナントレジストリに置き換えてはいません。fetcher の作成前に ASGI middleware で渡された Jira/Confluence URL を検証し、その後 response hook を追加してリダイレクト先も検証します。強化例はこの2つの upstream 制御を示し、validator の実装は省略しています。サーバー側テナントレジストリはより強固な代替設計であり、このパッチが実装したものではありません。0.22.0 の後続アドバイザリには別の残存経路が記載されているため、内容を確認せずに 0.17.0 を全環境の最低バージョンとしないでください。DNS rebinding を防ぐには接続時にも DNS 検証を適用する必要があり、ホスト名を一度解決するだけでは SSRF 境界を完全には閉じられません。[1], [2]

ソース抜粋: 上流パッチのミドルウェアおよびfetcher抜粋(Jira経路。Confluenceにも同等の検査があります)。

脆弱な実装
header_jira_fetcher = JiraFetcher(config=header_config)
current_user_id = header_jira_fetcher.get_current_user_account_id()
堅牢化されたセキュアパッチ
ssrf_error = validate_url_for_ssrf(jira_url_str)
if ssrf_error:
    scope["state"]["auth_validation_error"] = (
        f"Forbidden: Invalid Jira URL - {ssrf_error}"
    )
    return

header_jira_fetcher = JiraFetcher(config=header_config)
header_jira_fetcher.jira._session.hooks["response"].append(
    _make_ssrf_safe_hook(validate_url_for_ssrf)
)
current_user_id = header_jira_fetcher.get_current_user_account_id()

エンジニアリング&システム堅牢化チェックリスト

参考資料