FlawOpen

flawopen.com/Teardowns/cve-2026-77244-mcp-atlassian-http-auth-bypass

● CVE-2026-77244 · CVSS 10.0[1] · Kritis
Riset Keamanan · FlawOpen

CVE-2026-77244: akses HTTP tanpa autentikasi pada mcp-atlassian

CVE-2026-77244 memungkinkan pemanggil tanpa autentikasi mencapai handler alat HTTP pada proyek komunitas mcp-atlassian, yang dapat menggunakan kredensial Jira atau Confluence dari lingkungan operator. Perbaikan utama tersedia di 0.22.0; pengguna SSE memerlukan 0.23.1 atau lebih baru untuk menutup cacat transport terpisah yang terkait.[1], [4], [5], [6]

Vektor CVSSCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N[1]
💡 Penjelasan Sederhana (ELI5)

Meja resepsionis seharusnya memeriksa lencana pengunjung sebelum membuka pintu khusus staf. Dalam alur lama, jika pengunjung tidak membawa lencana, resepsionis meminjamkan kunci utama. Cacat ini menggabungkan dua pemeriksaan yang hilang: permintaan HTTP dapat mencapai alat tanpa identitas pengguna terverifikasi, lalu alat dapat memakai kredensial Atlassian bersama milik operator. Perbaikan menolak permintaan HTTP tanpa autentikasi dan membuat fallback kredensial harus diaktifkan secara eksplisit.[1], [3]

Konsep Kunci & Istilah

Transport MCP
Kanal yang membawa permintaan Model Context Protocol antara klien dan server. CVE ini mengenai transport HTTP mcp-atlassian; advisory menyatakan stdio tidak terdampak.[1], [4]
Fallback kredensial global
Menggunakan kredensial Jira atau Confluence di lingkungan server saat permintaan tidak memiliki identitas pengguna sendiri. Pada HTTP yang dapat dijangkau dari jarak jauh, permintaan anonim dapat bertindak sebagai operator.[1], [4]
Batas autentikasi
Pemeriksaan di sisi server yang memastikan identitas pemanggil sebelum permintaan masuk ke handler alat terlindungi. Keterjangkauan jaringan, string token yang tidak kosong, atau asumsi percaya pada proxy bukan bukti identitas.[1], [7]
CWE-287
Autentikasi tidak tepat: aplikasi tidak cukup membuktikan identitas yang diklaim sebelum memberi akses.[1], [7]
CWE-303
Verifier token menerapkan autentikasi secara keliru: verifier menerima token apa pun yang tidak kosong tanpa memeriksa validitasnya.[1], [9]
CWE-862
Permintaan HTTP dapat mencapai handler alat berhak istimewa tanpa pemeriksaan otorisasi yang mewajibkan identitas pengguna terverifikasi.[1], [10]

Pemetaan kerangka kerja

Analisis Akar Masalah (Root Cause)

Advisory keamanan GitHub menjelaskan rantai di proyek komunitas mcp-atlassian, bukan kerentanan produk Atlassian. Sebelum 0.22.0, middleware HTTP dapat meneruskan permintaan tanpa identitas pengguna ke handler alat. Jika deployment menggunakan kredensial operator dari environment, JiraFetcher atau ConfluenceFetcher dapat beralih ke kredensial global tersebut. Advisory juga mencatat verifier token opaque yang menerima string apa pun yang tidak kosong; perilaku itu tidak membuktikan identitas pemanggil yang sebenarnya. Batas keamanan harus melindungi identitas permintaan dan pemilihan kredensial sekaligus: pengguna yang tidak ada atau belum diverifikasi tidak boleh mewarisi kredensial operator yang istimewa. Perbaikan 0.22.0 mengembalikan HTTP 401 untuk POST MCP streamable-HTTP tanpa autentikasi dan memblokir fallback global dalam konteks HTTP kecuali ALLOW_GLOBAL_CRED_FALLBACK=true secara eksplisit diatur untuk deployment satu pengguna. Perilaku stdio tidak berubah. Secara terpisah, GHSA-5j8j-256g-vvp5 menjelaskan ketidakcocokan jalur SSE yang diperbaiki di 0.23.1; itu bukan CVE-2026-77244. Perbarui deployment SSE ke 0.23.1 atau lebih baru dan jangan menganggap patch CVE 0.22.0 juga memperbaiki advisory terpisah tersebut. Advisory tidak mengonfirmasi eksploitasi; artikel ini tidak mengklaim adanya pembobolan nyata. Advisory CVE mencantumkan CWE-287, CWE-303, dan CWE-862 untuk kelemahan autentikasi, verifikasi token, dan otorisasi dalam rantai ini. Advisory tersebut mencantumkan crazydude123 sebagai pelapor.[1], [3], [4], [5], [6], [7], [9], [10]

Alur Serangan Langkah demi Langkah

Langkah 1

Endpoint HTTP MCP dapat dijangkau

Deployment menjalankan server komunitas mcp-atlassian melalui HTTP dan pihak tanpa autentikasi dapat mencapai transportnya. Deployment yang hanya memakai stdio berada di luar jalur terdampak CVE ini.[1]

Langkah 2

Permintaan mencapai alat tanpa pengguna terverifikasi

Sebelum 0.22.0, permintaan HTTP tanpa identitas sendiri dapat melewati middleware alih-alih ditolak di batas transport. Advisory juga menyebut string yang tidak kosong tidak diverifikasi secara mandiri sebagai identitas.[1], [3]

Langkah 3

Alat memilih kredensial bersama milik operator

Jika tidak ada identitas pengguna dan lingkungan server berisi kredensial Jira atau Confluence, fetcher dapat memakai kredensial global. Permintaan kemudian dapat menggunakan izin alat yang diaktifkan untuk operator; dampak pastinya bergantung pada hak akun dan konfigurasi.[1], [3]

Langkah 4

Tolak di transport dan fail closed saat memilih kredensial

Versi 0.22.0 mengembalikan HTTP 401 untuk permintaan streamable-HTTP tanpa autentikasi dan memblokir fallback global dalam konteks HTTP tanpa opt-in eksplisit. Untuk SSE, pasang 0.23.1 atau lebih baru karena cacat pencocokan jalur terpisah diperbaiki di sana.[1], [4], [5], [6]

Kode Sumber: Rentan vs Aman

Ini adalah representasi ringkas alur kontrol, bukan salinan lengkap fungsi secara verbatim. Patch upstream menambahkan HTTP 401 di batas transport dan pemeriksaan kedua sebelum mengembalikan fetcher global dalam konteks HTTP.[1], [3], [4]

IMPLEMENTASI RENTAN
# Representasi sederhana dari alur kontrol yang terdampak.
async def handle_request(scope, ctx):
    user_identity = scope.get("state", {}).get("user_atlassian_auth_type")
    # Identitas yang tidak ada tidak ditolak di batas HTTP.
    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)
    # Sebagai fallback, gunakan kredensial operator dari konfigurasi lingkungan.
    return fetcher_from_config(global_config)
PERBAIKAN AMAN & KUAT
# Representasi terfokus dari perlindungan yang digabungkan pada versi 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)

Daftar Periksa Penguatan Sistem Rekayasa

Sumber