یک سرور مخرب MCP میتواند اپلیکیشنی را که با MCP Python SDK رسمی ساخته شده، فریب دهد تا اطلاعات احراز هویت OAuth خود را که برای ورود به یک سرویس واقعی استفاده میکند، در اختیار مهاجم قرار دهد. نگهدارندگان SDK این موضوع را در یک هشدار امنیتی اعلام کردهاند.
نسخههای آسیبپذیر، client secret، کد مجوز یا authorization code و کلید اثبات PKCE را به یک token endpoint که تحت کنترل مهاجم بود ارسال میکردند. این مشکل در نسخههای ۱.۳۰.۰ و ۲.۲.۰ برطرف شده است.
Model Context Protocol یا MCP یک استاندارد باز برای اتصال اپلیکیشنهای هوش مصنوعی به ابزارها و دادههای بیرونی است و این پکیج نیز SDK رسمی پایتون آن برای ساخت سرورها و کلاینتهای MCP محسوب میشود.
با استفاده از اطلاعات احراز هویت سرقتشده، مهاجم میتواند از سرویس واقعی ورود، یک access token معتبر درخواست کند. شرکت امنیتی Cycode که این آسیبپذیری را گزارش کرده است، در یک آزمایش کل این فرایند را بهطور عملی نشان داده و میگوید توکن بهدستآمده تمام مجوزهایی را خواهد داشت که قبلا به اپلیکیشن داده شده بودند. client secret نیز معمولا عمر طولانی دارد، بنابراین تا زمانی که تغییر داده نشود، همچنان قابل استفاده خواهد بود.
شدت این آسیبپذیری برای دو Provider که بدون حضور کاربر اجرا میشوند، «بالا» و با امتیاز ۷.۵ ارزیابی شده است. برای Provider تعاملی که در آن یک شخص باید فرایند ورود را آغاز کند، امتیاز ۶.۵ در نظر گرفته شده است. تا تاریخ ۲۹ سپتامبر هنوز هیچ شناسه CVEای برای این آسیبپذیری اختصاص داده نشده بود.
سرور چگونه اطلاعات احراز هویت را سرقت میکند؟
وقتی یک کلاینت MCP نیاز به ورود دارد، از سروری که به آن متصل میشود میپرسد سرویس ورود آن، که authorization server نام دارد، در کجا قرار گرفته است. در نسخههای آسیبپذیر، SDK همیشه پاسخ سرور را بررسی و اعتبارسنجی نمیکرد.
در نتیجه، یک سرور مخرب میتوانست کلاینت را به یک سرویس ورود تحت کنترل مهاجم هدایت کند. این کار میتوانست به دو شکل انجام شود: یا سرور مهاجم مستقیما بهعنوان سرویس ورود معرفی شود، یا اطلاعات ورود بهگونهای ارائه شود که ظاهرا سرویس واقعی کاربر را معرفی کند، اما اطلاعات احراز هویت عملا به مقصد دیگری ارسال شوند.
سپس کلاینت بهجای سرویس واقعی، client secret، کد مجوز و کلید اثبات PKCE خود را برای مهاجم ارسال میکند.
کلید اثبات PKCE یک مقدار یکبارمصرف است که برای جلوگیری از استفاده مجدد از یک authorization code سرقتشده طراحی شده است. بنابراین اگر این کلید نیز در اختیار مهاجم قرار بگیرد، این لایه حفاظتی عملا بیاثر میشود.
در Provider تعاملی، کاربر همچنان باید ورود را تایید کند. به گفته Cycode، صفحهای که کاربر تایید میکند همان صفحه واقعی ورود است و بنابراین هیچ چیز مشکوکی به نظر نمیرسد.
اما دو Provider مخصوص ارتباط ماشینبهماشین نه به فرایند ورود کاربر نیاز دارند و نه اصلا حضور یک انسان را لازم دارند.
چه کسانی تحت تاثیر هستند؟
یک اپلیکیشن در صورتی آسیبپذیر است که از SDK بهعنوان یک کلاینت MCP روی HTTP استفاده کند و یکی از Providerهای OAuth زیر را به کار گرفته باشد:
OAuthClientProviderClientCredentialsOAuthProviderPrivateKeyJWTOAuthProvider- یا
RFC7523OAuthClientProviderقدیمی در شاخه ۱.x
علاوه بر این، اپلیکیشن باید بتواند به سروری متصل شود که کاملا تحت کنترل و اعتماد خودش نیست، در حالی که اطلاعات احراز هویت مربوط به یک سرویس ورود واقعی را نیز در اختیار دارد.
سرورهای MCP ساختهشده با این SDK، کلاینتهای محلی مبتنی بر stdio و کلاینتهایی که توکنهای خودشان را مستقیما ضمیمه میکنند، تحت تاثیر این آسیبپذیری نیستند.
| شاخه | نسخههای آسیبپذیر | نسخه اصلاحشده |
|---|---|---|
| 1.x | از ۱.۹.۱ تا ۱.۲۹.۱ | 1.30.0 |
| 2.x | از ۲.۰.۰ تا ۲.۱.۱ | 2.2.0 |
چه باید کرد؟
اگر از شاخه ۱.x استفاده میکنید، به نسخه ۱.۳۰.۰ ارتقا دهید و اگر روی شاخه ۲.x هستید، از نسخه ۲.۲.۰ استفاده کنید.
در نسخههای اصلاحشده، کلاینت پیش از دریافت هرگونه اطلاعات، ابتدا مشخص میکند که انتظار دارد با کدام سرویس ورود ارتباط داشته باشد و اگر اطلاعات دریافتشده به سرویس دیگری اشاره کنند، آنها را رد میکند.
با این حال، برای دو Provider فقط ارتقای نسخه کافی نیست.
اگر از ClientCredentialsOAuthProvider یا PrivateKeyJWTOAuthProvider استفاده میکنید، طبق هشدار امنیتی «ارتقا هیچ تغییری ایجاد نمیکند، مگر اینکه پارامتر issuer= را نیز مشخص کنید».
این پارامتر مشخص میکند اطلاعات احراز هویت متعلق به کدام سرویس ورود هستند. بدون آن، این Providerها همچنان ممکن است هر سرویسی را دنبال کنند که سرور MCP به آنها معرفی میکند.
در نسخه ۱.۳۰.۰، هشدار مربوط به این موضوع بهصورت یک deprecation warning معمولی نمایش داده میشود. پایتون این نوع هشدارها را بهطور پیشفرض مخفی میکند، بنابراین ممکن است بهراحتی نادیده گرفته شود.
Provider قدیمی RFC7523OAuthClientProvider نیز اصلا گزینه issuer= ندارد، بنابراین باید به یکی از دو Provider دیگر مهاجرت کنید.
پس از ارتقا، باید یک بار تمام OAuth client registrationهای ذخیرهشده را پاک کنید، زیرا ثبتهای قدیمی به هیچ سرویس ورود مشخصی متصل نشدهاند و این وضعیت پس از ارتقا نیز خودبهخود تغییر نمیکند.
اگر احتمال میدهید کلاینت قبلا به یک سرور غیرقابلاعتماد متصل شده باشد، باید client secret آن را تغییر دهید و توکنهایش را نیز در سرویس ورود لغو کنید.
در نسخههای قدیمی هیچ راهحل جایگزین کاملی وجود ندارد، جز اینکه فقط به سرورهای MCP مورداعتماد متصل شوید.
افشای آسیبپذیری
بررسیهای مربوط به issuer در نسخههای ۱.۳۰.۰ و ۲.۲.۰ و در یادداشت انتشار مورخ ۷ سپتامبر عرضه شدند، اما در آن زمان بهعنوان «تغییر در رفتار» معرفی شده بودند، نه یک اصلاح امنیتی.
هشدار امنیتی رسمی در ۲۸ سپتامبر منتشر شد؛ همان روزی که Cycode نیز گزارش خود را منتشر کرد.
در هشدار امنیتی از هشت گزارشدهنده، از جمله پژوهشگر Cycode، قدردانی شده است.
نه هشدار رسمی و نه Cycode گزارشی از سوءاستفاده واقعی از این آسیبپذیری ارائه نکردهاند و تا زمان انتشار این مطلب نیز موردی از حمله با استفاده از آن در منابع دیگر گزارش نشده بود.






