تصور کنید تنها با ارسال دو درخواست ساده به سرور، بتوانید هر کدی را در زیرساختهای تولیدی یکی از بزرگترین شرکتهای فناوری جهان اجرا کنید. این سناریوی ترسناک، دقیقاً همان چیزی است که یک پژوهشگر امنیتی در پلتفرم مشترک مستندات توسعهدهندگان گوگل کشف کرد. گوگل در نهایت مبلغ ۹۰,۰۰۰ دلار را به عنوان پاداش برای کشف این آسیبپذیری پرداخت کرد.
به نقل از گزارش منتشر شده در ۱۲ اکتبر ۲۰۲۶، این آسیبپذیری اجرای کد از راه دور (Remote Code Execution یا RCE) — شبیه به داشتن یک کلید تقلبی که نه تنها در را باز میکند، بلکه اجازه میدهد هر تغییری در دکوراسیون خانه بدهید — در زیرساخت مشترک DevSite گوگل رخ داده است. این نقص امنیتی تنها یک اپلیکیشن را هدف قرار نداد، بلکه دامنههای پربازدیدی مانند firebase.google.com، developer.android.com، source.android.com و docs.partner.android.com را در معرض خطر قرار داد. همانطور که در تحلیلهای قبلی ما دربارهی ابزارهایی مانند Google Playground اشاره کردیم، این حادثه یادآور این نکته است که حتی پیشرفتهترین اکوسیستمهای مبتنی بر هوش مصنوعی نیز در برابر خطاهای بنیادین امنیتی آسیبپذیرند. این موضوع در کنار حملات پیچیدهتری که گواهنامههای امنیتی گوگل را هدف قرار داده بودند، نشان میدهد که حتی غولهای فناوری نیز در برابر زنجیرهای از خطاهای پیکربندی آسیبپذیر هستند.
زمینه و جزئیات کشف
پژوهشگر این نقص را هنگام بررسی و نقشهبرداری از جریان OAuth (پروتکلی برای احراز هویت بدون اشتراک رمز عبور) در سایتهای مستندات توسعهدهندگان گوگل یافت. او متوجه شد که با ارسال یک درخواست به مسیر /oauth2authorize، سرور یک کوکی نشست Flask (یک چارچوب وب برای پایتون) تنظیم کرده و کاربر را به صفحه ورود هدایت میکند.
برای فعال کردن این فرآیند، نیازی به داشتن حساب کاربری نبود؛ یک دستور ساده curl به این نقطه انتهایی (Endpoint) همراه با یک return_url کافی بود تا کوکی مورد نظر دریافت شود. پژوهشگر متوجه شد که این کوکی بهطور غیرعادی بزرگ است — حدود ۱۲۰۰ بایت — که بسیار بیشتر از مقدار مورد نیاز برای یک توکن استاندارد CSRF و یک URL بازگشتی است.
طبق گزارش منتشر شده در simonkoeck.com، پژوهشگر دریافت که کوکیهای نشست Flask امضا شدهاند اما رمزنگاری نشدهاند. از آنجایی که محموله (Payload) با یک نقطه شروع میشد، این نشان میداد که دادهها با استفاده از zlib فشرده شدهاند. با رمزگشایی محموله base64 و باز کردن فشار آن، پژوهشگر متوجه شد که گوگل client_id و client_secret مربوط به OAuth را بهصورت متن ساده (Plaintext) در داخل نشست ذخیره کرده است.
تحلیل فنی آسیبپذیری
این فاجعه امنیتی حاصل تلاقی و همپوشانی فاجعهبار دو اشتباه امنیتی بود:
- استفاده مجدد از کلید (Key Reuse): پژوهشگر دریافت که رمز مخفی (Client Secret) مربوط به OAuth دقیقاً به عنوان
SECRET_KEYدر Flask استفاده شده است. برای تأیید این موضوع، او امضا را بهصورت آفلاین با استفاده ازhmac.digestو مشتقسازی کلیدcookie-sessionو الگوریتم SHA1 بازسازی کرد. نتیجه بهطور دقیق (بایت به بایت) با امضای کوکی یکسان بود. این موضوع به مهاجم اجازه میداد تا کوکیهای نشست معتبر را بهصورت آفلاین جعل کند. - واسریالسازی ناامن (Unsafe Deserialization): سرور برای پردازش دادههای نشست از تابع
pickle.loads()در پایتون استفاده میکرد. جریان کار به این صورت بود: سرور ابتدا امضای Flask را تأیید میکرد، سپس ورودیgoogle_oauth2_flow_<csrf>را میخواند، بایتها را از حالت base64 خارج میکرد و آنها را بهpickle.loads()میسپرد. از آنجایی که مهاجم اکنون میتوانست کوکیهای خود را امضا کند، میتوانست یک محموله مخرب «pickle» تزریق کند که سرور هنگام باز کردن آن (Unpickling)، کد را اجرا میکرد.
اثبات اکسپلویت
برای اثبات این حمله بدون آسیب زدن به سیستمهای تولیدی، پژوهشگر از یک محموله time.sleep(N) استفاده کرد. این کار از طریق کد عملیاتی REDUCE انجام شد که نام یک تابع قابل فراخوانی و آرگومانهای آن را برای اجرا به unpickler میدهد.
با مشاهده اینکه پاسخ سرور دقیقاً به تعداد ثانیههای مشخص شده در کوکی جعل شده تأخیر داشت، پژوهشگر اجرای کد (RCE) را تأیید کرد. نتایج بسیار دقیق بودند:
time.sleep(0)$\rightarrow$ ۰.۲۰۷ ثانیهtime.sleep(3)$\rightarrow$ ۳.۱۹۳ ثانیهtime.sleep(5)$\rightarrow$ ۵.۱۹۴ ثانیهtime.sleep(8)$\rightarrow$ ۸.۲۸۳ ثانیه
برای حذف احتمال نوسانات شبکه (Network Jitter)، پژوهشگر تستهای کنترلی انجام داد: کوکی با یک بایت تغییر یافته در امضا، یا کوکی با امضای معتبر اما بدون ورودی flow، هر دو منجر به خطای "Invalid request" شدند، در حالی که محموله sleep دقیقاً تأخیر مورد نظر را ایجاد کرد.
این کشف نشاندهنده شکست بحرانی در فلسفه «دفاع در عمق» (Defense in Depth) است. پژوهشگر اشاره کرد که هر یک از چهار راهکار زیر میتوانست زنجیره حمله را قطع کند:
۱. چرخش (Rotate) رمزهای مخفی OAuth که لو رفته بودند و ابطال تمام نشستهای امضا شده با آنها.
۲. اختصاص یک SECRET_KEY با آنتروپی بالا و مجزا برای هر استقرار (Deployment) از طریق یک ذخیرهساز سمت سرور.
۳. نگه داشتن شیء جریان OAuth در سمت سرور و استفاده از یک مرجع غیرشفاف (Opaque Reference) در کوکی.
۴. جایگزینی pickle با یک فرمت دادهای صرف (Data-only) همراه با بررسی طرحواره (Schema Check) برای بیاثر کردن کوکیهای جعل شده.
برای توسعهدهندگان، این یک مورد آموزشی کلاسیک است که چرا اسرار (Secrets) هرگز نباید در کوکیهای سمت کاربر ذخیره شوند و چرا pickle نباید برای دادههایی که از مرز اعتماد (Trust Boundary) عبور میکنند استفاده شود. اثر ثانویه این اتفاق، هشداری است برای هر سازمانی که از پلتفرمهای مشترک استفاده میکند؛ یک کلید لو رفته در یک زیردامنه میتواند کل ناوگان سرورها را به خطر اندازد اگر زیرساخت امضای آنها مشترک باشد. در همین راستا، استفاده از ابزارهای پیشرفته شناسایی آسیبپذیری مانند عاملهای هوش مصنوعی گیتهاب میتواند به سازمانها کمک کند تا پیش از کشف توسط پژوهشگران خارجی، این حفرههای بحرانی را شناسایی کنند.
تیمهای امنیتی اکنون باید مدیریت نشستهای خود را بازرسی کنند تا مطمئن شوند کلیدهای امضا از اعتبارنامههای API متمایز هستند. میتوانید با تأیید اینکه هیچ شیء حساسی مستقیماً در کوکیها سریالیزه نمیشود، این کار را شروع کنید.
گام بعدی شما
- اگر از Flask یا چارچوبهای مشابه استفاده میکنید، فوراً بررسی کنید که
SECRET_KEYشما با هیچ API Key یا رمز OAuth مشترک نباشد. - هرگونه استفاده از
pickleبرای پردازش دادههای ورودی کاربر را متوقف کرده و از فرمتهای امنتر استفاده کنید. - مدیریت نشستها را به سمت مدلهای Opaque Token (توکنهای غیرشفاف) ببرید تا دادههای حساس در سمت کاربر ذخیره نشوند.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو