flawopen.com/AI Security/mcp-python-sdk-oauth-issuer-confusion
Cacat validasi issuer OAuth pada MCP Python SDK
GHSA-qx49-fqc8-xw99 memungkinkan server MCP HTTP memengaruhi tujuan yang dapat menerima kredensial dari klien OAuth Python SDK yang terdampak. Tingkatkan ke mcp 1.30.0 atau 2.2.0; provider antarmesin harus menetapkan issuer=. Tidak ada CVE yang ditetapkan.[1], [3], [8]
Sebuah perusahaan mengirim kunci tersegel ke bank yang alamatnya tercantum pada kartu direktori yang disetujui. Server MCP dapat memberikan kartu tersebut, sementara satu jalur cadangan tidak memeriksa apakah entri itu benar-benar milik bank yang diharapkan. Validasi issuer membandingkan identitas pada kartu dengan bank tepercaya yang dikonfigurasi sebelum kunci dikirim.[1], [2]
Konsep Kunci & Istilah
Klien MCP- Aplikasi yang menggunakan Model Context Protocol untuk terhubung ke alat atau data dari server MCP. Celah ini berdampak saat Python SDK digunakan sebagai klien HTTP dengan provider OAuth-nya.[1]
Issuer authorization server- Pengenal stabil untuk layanan OAuth yang menerbitkan token. Klien harus membandingkan metadata yang ditemukan dengan issuer yang diharapkan secara independen.[1], [2]
Protected Resource Metadata (PRM)- Metadata yang dapat menunjukkan authorization server untuk sumber daya terlindungi. SDK juga memiliki jalur penemuan lama ketika PRM tidak tersedia.[1], [2]
Pemetaan kerangka kerja
Alur Serangan Langkah demi Langkah
Klien HTTP MCP menyimpan kredensial OAuth
Aplikasi menggunakan versi mcp yang terdampak dan salah satu provider OAuth SDK. Aplikasi dapat terhubung ke server MCP yang tidak sepenuhnya tepercaya sambil menyimpan rahasia klien, kunci penandatanganan, atau registrasi klien.[1]
Server memengaruhi penemuan otorisasi
mcp 1.9.1–1.29.1 tidak memvalidasi issuer dan tidak mengikat kredensial pada semua jalur discovery. mcp 2.0.0–2.1.1 terdampak saat PRM tidak tersedia dan fallback lama berjalan, atau saat discovery setelah 403 insufficient_scope. Pada kedua lini, provider antarmesin tidak memiliki issuer= untuk mengikat kredensial yang telah disediakan. Rentang versi paket dalam advisory adalah >=2.0.0a1, <2.2.0; prarilis 2.0.0 yang terdampak juga termasuk.[1], [3], [8]
Dampak bergantung pada provider dan izin
Penerima dapat menggunakan kredensial atau token yang terekspos sesuai cakupan izin. Advisory memberi nilai CVSS 7,5 untuk provider tanpa interaksi; provider interaktif bernilai 6,5 karena seseorang harus memulai login. Advisory menyatakan bahwa belum ada CVE yang ditetapkan.[1]
Matriks versi dan tindakan OAuth MCP Python SDK
| Konfigurasi klien | Kondisi terdampak yang didokumentasikan | Tindakan yang diperlukan |
|---|---|---|
Klien HTTP OAuth dengan mcp 1.9.1–1.29.1 | Semua jalur discovery tidak memiliki validasi issuer dan pengikatan kredensial ke issuer secara konsisten. | Tingkatkan ke mcp 1.30.0 atau lebih baru; verifikasi versi yang benar-benar diterapkan. |
Klien HTTP OAuth dengan mcp 2.0.0–2.1.1 | Terdampak jika PRM tidak ada dan fallback lama digunakan, atau saat discovery step-up 403 insufficient_scope. Rentang versi paket dalam advisory adalah >=2.0.0a1, <2.2.0; prarilis 2.0.0 yang terdampak juga termasuk. | Tingkatkan ke mcp 2.2.0 atau lebih baru; verifikasi versi yang benar-benar diterapkan. |
ClientCredentialsOAuthProvider atau PrivateKeyJWTOAuthProvider dengan kredensial yang telah disediakan | Versi terdampak tidak memiliki opsi issuer= untuk mengikat kredensial ke server otorisasi yang semestinya. | Setelah meningkatkan versi, tetapkan issuer= secara eksplisit. Migrasikan RFC7523OAuthClientProvider yang deprecated di lini 1.x. |
| Server yang dibuat SDK, klien stdio, atau klien yang memasok token/header sendiri | Tidak terdampak menurut advisory ini. | Tidak perlu tindakan untuk kelemahan khusus ini; nilai ulang jika aplikasi juga memakai klien HTTP OAuth yang terdampak. |
Analisis Akar Masalah (Root Cause)
Kegagalan batas kepercayaan ini memiliki dua bagian terkait: beberapa jalur discovery yang terdampak tidak selalu membandingkan issuer pada metadata server otorisasi dengan issuer yang diharapkan secara independen dari server MCP, dan kredensial tersimpan atau yang disediakan sebelumnya tidak terikat pada issuer tujuan. Karena itu, server MCP berbahaya atau yang telah disusupi dapat mengarahkan pertukaran token ke endpoint yang dikendalikannya dan menerima materi OAuth milik klien. Perbaikan menentukan issuer yang diharapkan sebelum discovery, menolak ketidakcocokan, dan mengikat registrasi tersimpan ke issuer tersebut; provider machine-to-machine tanpa interaksi juga memerlukan issuer= eksplisit.[1], [2]
Kode Sumber: Rentan vs Aman
Argumen issuer tersedia pada rilis SDK yang telah diperbaiki. Argumen ini mengikat kredensial antarmesin ke authorization server yang benar, tetapi tidak menggantikan upgrade, penghapusan registrasi lama yang belum terikat, atau rotasi kredensial yang mungkin terekspos.[2], [3], [8]
Cuplikan sumber: mcp.client.auth
import os
from mcp.client.auth import ClientCredentialsOAuthProvider
auth = ClientCredentialsOAuthProvider(
client_id=os.environ["MCP_CLIENT_ID"],
client_secret=os.environ["MCP_CLIENT_SECRET"],
)
import os
from mcp.client.auth import ClientCredentialsOAuthProvider
auth = ClientCredentialsOAuthProvider(
client_id=os.environ["MCP_CLIENT_ID"],
client_secret=os.environ["MCP_CLIENT_SECRET"],
issuer=os.environ["MCP_AUTH_ISSUER"],
)
# Gunakan mcp >= 1.30.0 (1.x) atau >= 2.2.0 (2.x).
Daftar Periksa Penguatan Sistem Rekayasa
- ✓Inventarisasi klien HTTP MCP dan pastikan versi
mcpyang terpasang, termasuk dependensi transitif dan image kontainer.[1] - ✓Tingkatkan klien 1.x ke
mcp1.30.0 atau lebih baru, dan klien 2.x ke 2.2.0 atau lebih baru; verifikasi lockfile dan lingkungan yang diterapkan.[1], [3], [8] - ✓Tetapkan
issuer=padaClientCredentialsOAuthProviderdanPrivateKeyJWTOAuthProvider; migrasikanRFC7523OAuthClientProvider1.x yang usang karena tidak memiliki opsi tersebut.[1], [2] - ✓Hapus registrasi OAuth tersimpan yang dibuat sebelum pengikatan issuer, lalu daftarkan ulang. Untuk rekaman praregistrasi yang Anda buat sendiri, tetapkan issuer secara eksplisit.[1], [2]
- ✓Panduan implementasi FlawOpen: Perlakukan server MCP yang tidak tepercaya sebagai batas kepercayaan tempat kredensial dapat dikirim. Jangan hubungkan ke klien berisi rahasia OAuth atau kunci penandatanganan produksi tanpa izin kebijakan.[1]
- ✓Jika klien terdampak mungkin pernah terhubung ke server yang tidak tepercaya, rotasi rahasia klien dan cabut token di authorization server.[1]
- ✓Tambahkan tes regresi untuk jalur discovery 1.x dan 2.x, issuer yang tidak cocok, PRM yang tidak ada,
403 insufficient_scope, registrasi yang terikat issuer, dan provider antarmesin tanpaissuer=.[2] - ✓Tinjau cakupan advisory ini sebelum menyatakan klien lain terdampak: server yang dibuat dengan SDK, klien stdio, dan klien yang memasok token atau header sendiri tidak terdampak.[1]
Sumber
- GitHub-reviewed advisory GHSA-qx49-fqc8-xw99
- MCP Python SDK pull request #3398: Validate issuer on every discovery path
- MCP Python SDK v1.30.0 release notes
- MITRE CWE-345: Insufficient Verification of Data Authenticity
- The Hacker News: Official MCP Python SDK flaw can let malicious servers steal OAuth credentials
- Cycode disclosure: MCP Python SDK OAuth flaw
- CWE-522: Insufficiently Protected Credentials
- MCP Python SDK v2.2.0 release