توسعه دهنده نرم افزار

الگوی حمله به GitHub Actions که اسکنرهای امنیتی CI شما آن را نمی‌بینند

۱۶ تیر ۱۴۰۵ - ۱۴:۰۱ پوریا فیاضی 2 بازدید
post image

سبز بودن پایپ‌لاین به معنی تحت کنترل بودن آن نیست، و گسترش کدنویسی عامل‌محور یا Agentic Coding این شکاف را سریع‌تر از آنچه فرایندهای بازبینی بتوانند جبران کنند، عمیق‌تر کرده است.

شین واردن، معمار ارشد ActiveState، در این یادداشت به یک ضعف مهم در زنجیره CI/CD اشاره می‌کند که به گفته او بسیاری از ابزارهای امنیتی رایج قادر به شناسایی آن نیستند.

در ژوئن ۲۰۲۶، پژوهشگران شرکت Novee Security دسته‌ای از ضعف‌های CI/CD را افشا کردند که آن را Cordyceps نام‌گذاری کردند. آن‌ها حدود ۳۰ هزار مخزن پراثر در اکوسیستم‌های npm، PyPI، crates.io و Go را بررسی کردند، سپس ۶۵۴ مورد را علامت‌گذاری کردند و بیش از ۳۰۰ مورد را کاملاً قابل سوءاستفاده تأیید کردند.

ابزارهای ساخت آسیب‌پذیر شامل پروژه‌هایی بودند که توسط مایکروسافت، گوگل، آپاچی، Cloudflare و Python Software Foundation منتشر شده‌اند. در عین حال، تنها چیزی که یک مهاجم برای ورود به این زنجیره نیاز دارد، یک حساب رایگان گیت‌هاب است؛ نه عضویت در سازمان لازم است و نه سطح دسترسی ویژه.

نکته نگران‌کننده اینجاست که تمام این پایپ‌لاین‌ها در ظاهر سالم بودند. اسکنرها اجرا می‌شدند، بررسی‌ها با موفقیت پاس می‌شدند و داشبوردها در تمام مدتی که این ضعف وجود داشت، وضعیت را عادی و بدون مشکل نشان می‌دادند. دلیلش این است که این اسکنرها اساساً برای دیدن چنین خطری ساخته نشده‌اند.

آسیب‌پذیری در «ترکیب» است، نه در یک فایل

گردش‌کارهای GitHub Actions معمولاً با pull_request اجرا می‌شوند؛ حالتی که در بستر غیرقابل‌اعتماد فورک اجرا می‌شود، بدون دسترسی به secrets مخزن و تنها با یک توکن فقط‌خواندنی. اما مشکل از جایی آغاز می‌شود که pull_request_target و workflow_run وارد ماجرا می‌شوند؛ دو حالتی که در بستر مخزن اصلی اجرا می‌شوند و به secrets و همچنین GITHUB_TOKEN با دسترسی خواندن و نوشتن دسترسی دارند.

یک مهاجم می‌تواند هر دو را وادار کند روی محتوایی عمل کنند که از همان pull request مهاجم آمده است. GitHub Security Lab این الگو را «pwn request» می‌نامد.

سه سازوکار اصلی باعث این سوءاستفاده می‌شوند. نخست، تزریق فرمان یا Command Injection است؛ یعنی داده‌ای که مهاجم کنترل می‌کند، مانند نام شاخه، عنوان یا کامنت، مستقیم داخل یک مرحله run قرار می‌گیرد و بدون Escape شدن وارد فرمان شل می‌شود و اجرا می‌شود.

دوم، تزریق کد از طریق actions/github-script است که ورودی مهاجم را در زمان اجرا به‌عنوان جاوااسکریپت ارزیابی می‌کند.

سوم نیز ارتقای سطح دسترسی بین چند گردش‌کار است؛ به این صورت که یک workflow کم‌دسترسی، داده غیرقابل‌اعتماد را در artifact یا output ذخیره می‌کند و سپس یک workflow دوم با دسترسی بالا، همان داده را می‌خواند و با توکن نگه‌دارنده مخزن روی آن عمل می‌کند. هیچ‌کدام از این دو workflow به‌تنهایی قابل سوءاستفاده نیستند.

آسیب‌پذیری دقیقاً از نحوه اتصال این اجزا به یکدیگر به وجود می‌آید و به همین دلیل است که اسکنرها همچنان چراغ سبز نشان می‌دهند. ابزارهای SAST یا DAST معمولاً فقط یک فایل را الگو‌محور بررسی می‌کنند و در اینجا هر فایل، یک YAML معتبر و درست‌ساخت است که دقیقاً همان کاری را انجام می‌دهد که برایش تعریف شده است.

واردن در این‌باره می‌گوید: «اسکنر یک workflow می‌بیند، اما مهاجم یک زنجیره چهارمرحله‌ای برای رسیدن به یک اعتبارنامه دائمی می‌بیند.»

در چنین حالتی، هیچ خط مشخصی وجود ندارد که بتوان آن را علامت‌گذاری کرد، چون هیچ خطی به‌تنهایی اشتباه نیست.

این بدترین نوع شکست در سنجش امنیت است؛ چون چراغ قرمز باعث می‌شود کسی دنبال مشکل بگردد، اما چراغ سبز باعث می‌شود همه با خیال راحت سراغ کار بعدی بروند.

یک Pull Request، دسترسی دائمی برای تغییر محتوای امنیتی منتشرشده

در مخزن Azure Sentinel متعلق به مایکروسافت، Novee نشان داد که یک کامنت روی pull request می‌تواند کد ناشناس مهاجم را روی CI مایکروسافت اجرا کند و یک کلید بدون انقضای GitHub App را سرقت کند؛ موضوعی که توسط Microsoft Security Response Center نیز تأیید شد.

Sentinel همان سامانه SIEM مایکروسافت است و Content Hub آن، قوانین تشخیص و playbookهای خودکار را مستقیماً به محیط‌های کاری مشتریان ارسال می‌کند.

سرقت چنین کلیدی به مهاجم دسترسی دائمی برای نوشتن در محتوای امنیتی می‌دهد؛ محتوایی که هزاران سازمان برای شناسایی حملات به آن متکی هستند. در نتیجه، مهاجم می‌تواند این محتوا را بی‌سروصدا تضعیف کند و آن را در قالب یک به‌روزرسانی ظاهراً قابل‌اعتماد به پایین‌دست زنجیره ارسال کند.

در نمونه‌ای دیگر، مخزن نمونه AI Agent Development Kit گوگل که هزاران توسعه‌دهنده برای ساخت عامل‌های هوش مصنوعی در Google Cloud از آن الگو می‌گیرند، نیز در معرض این الگو قرار داشت. یک pull request می‌توانست کد را در CI گوگل اجرا کند و سطح دسترسی را تا نقش roles/owner در پروژه Google Cloud مرتبط بالا ببرد؛ یعنی دسترسی دائمی در سطح مالک. گوگل نیز این موضوع را تأیید کرده است.

پروژه Apache Doris هم مسیر مشابهی برای سرقت اعتبارنامه داشت که توسط تیم امنیتی آپاچی تأیید و اصلاح شد.

سه سازمان، یک مشکل ترکیبی، و در عین حال هیچ خط کدی وجود نداشت که اسکنر بتواند دقیقاً به آن اشاره کند.

هیچ‌کس عمداً به آن Pull Request اعتماد نکرده بود

به گفته نویسنده، عبارتی که باید هر رهبر فنی را متوقف کند این است: «مرز اعتمادی که هیچ‌کس آن را ممیزی نکرده است.»

در عمل، کسی یک workflow را طوری پیکربندی کرده که ورودی یک فرد بیرونی را مثل ورودی یک نگه‌دارنده مخزن در نظر بگیرد؛ اما هیچ انسانی عمداً چنین تصمیمی نگرفته است.

این ریسک به‌مرور و با مجموعه‌ای از commitهای ظاهراً منطقی شکل گرفته و با افزایش استفاده از workflowهای تولیدشده توسط هوش مصنوعی، خطر آن بیشتر هم می‌شود؛ چون ممکن است اساساً لحظه تصمیم‌گیری هیچ‌وقت ممیزی نشده باشد.

واردن می‌گوید خودش ابزارهای هوش مصنوعی را وارد فرایند مهندسی تولید کرده و اثر آن‌ها را سنجیده است، بنابراین به‌صراحت تأکید می‌کند که بهره‌وری این ابزارها واقعی است و هدف او مخالفت با سرعت گرفتن آن‌ها نیست.

اما Novee به‌روشنی اعلام کرده که Agentic Coding در اینجا نقش چندبرابرکننده دارد. ابزارهای هوش مصنوعی پیکربندی‌های CI/CD را با سرعت تولید می‌کنند و همان الگوهای ناامن را نیز تکرار می‌کنند؛ در نتیجه، یک اشتباه می‌تواند در میلیون‌ها مخزن تکثیر شود، آن هم با ظاهری مطمئن و بدون هیچ نشانه‌ای از منشأ و اعتبار.

حجم تصمیم‌هایی که اکنون یک سازمان در حوزه workflow باید جذب و بررسی کند، از ظرفیتی که برای بازبینی انسانی و با سرعت انسان طراحی شده بود، فراتر رفته است.

سامانه‌های امنیتی رایج هم برای این وضعیت آماده نیستند. Cordyceps یک CVE نیست، بنابراین وارد مدل‌های استاندارد شمارش و ردیابی آسیب‌پذیری نمی‌شود. افزون بر این، NIST در آوریل ۲۰۲۶ اعلام کرد که دیگر نمی‌تواند همه CVEها را غنی‌سازی و تحلیل تکمیلی کند، زیرا تعداد گزارش‌ها از سال ۲۰۲۰ تاکنون ۲۶۳ درصد رشد کرده است. به بیان ساده، ریسک‌ها در حال تکثیرند.

خوشبختانه Novee اعلام کرده که هیچ شواهدی از سوءاستفاده عملی از این الگو در دنیای واقعی پیدا نکرده و شرکت‌های نام‌برده نیز وضعیت خود را سخت‌گیرانه‌تر کرده یا وصله‌های لازم را منتشر کرده‌اند. بااین‌حال، این یک الگوی اثبات‌شده و قابل بهره‌برداری است، نه فقط یک رخداد تکی، و در سطح صنعت نیز به‌صورت پیش‌فرض تا حد زیادی بدون وصله باقی مانده است.

ابتدا مرز اعتماد را ببندید، سپس آنچه از آن عبور می‌کند را کنترل کنید

راهکارهای فوری وجود دارند و بهتر است همین حالا اجرا شوند: برای مشارکت‌های غیرقابل‌اعتماد، pull_request را به pull_request_target ترجیح دهید؛ هیچ‌گاه کد شاخه pull request را داخل یک workflow دارای سطح دسترسی بالا checkout نکنید؛ داده‌های رویداد را از طریق یک متغیر محیطی quote‌شده عبور دهید، نه اینکه مستقیم آن را inline کنید؛ مجوزها را به‌صورت پیش‌فرض روی فقط‌خواندنی قرار دهید؛ اکشن‌های شخص ثالث را به‌جای تگ‌های شناور، به یک commit SHA ثابت pin کنید؛ و workflowهای دارای دسترسی ویژه را برای مشارکت‌کنندگان باراولی پشت تأیید دستی قرار دهید.

با انجام همه این کارها، مشکلات امروز تا حد زیادی برطرف می‌شوند، اما خود «دسته» این مشکلات از بین نمی‌رود. الگوی حمله بعدی نیز ممکن است از چند مرحله کاملاً درست و مجزا ساخته شود و باز هم از اسکن‌ها عبور کند. توسعه مبتنی بر هوش مصنوعی این شکاف حاکمیتی در زنجیره تأمین نرم‌افزار را گسترده‌تر کرده و سرعت آن هم رو به افزایش است.

کنترل پایدار این است که از همان نقطه ورود، بر چیزی که فرایند ساخت شما می‌تواند به آن اعتماد کند حاکمیت داشته باشید؛ به این معنا که مؤلفه‌ها و workflowهایی که وارد پایپ‌لاین شما می‌شوند، از منشأیی کنترل‌شده با منشأ و اصالت قابل‌راستی‌آزمایی بیایند و از سورس ساخته شده باشند، نه اینکه صرفاً بر پایه اعتماد پذیرفته شوند.

اگر یک منبع بالادستی هک شده، یک بسته آلوده منتشر کند، باید همان لحظه ورود به سیستم با یک کنترل مشخص مواجه شود و رد شود.

در نهایت، یک انسان باید مالک مرزهای اعتماد باشد. اما این مالکیت هم باید با سرعتی عمل کند که هوش مصنوعی اکنون با آن تصمیم تولید می‌کند، زیرا بازبینی دستی در انتهای پایپ‌لاین دیگر توان جبران این حجم را ندارد.

Cordyceps ابزارهای امنیتی هیچ‌کس را شکست نداد؛ فقط از کنار آن‌ها عبور کرد، چون هر جزء به‌تنهایی دقیقاً همان‌طور که طراحی شده بود کار می‌کرد. این خالص‌ترین شکل تله سنجش است: عدد سبز باقی می‌ماند، در حالی که چیزی که قرار بود آن عدد تضمینش کند، دیگر واقعیت ندارد؛ اگر اصلاً از ابتدا هم واقعیت داشته باشد.

این پایپ‌لاین‌ها به این دلیل در معرض خطر قرار نگرفتند که اسکنرها از کار افتاده بودند، بلکه به این دلیل آسیب‌پذیر شدند که پاس شدن اسکن به معنی تحت حاکمیت بودن آن‌ها نبود. برای مدتی، هیچ‌کس هم دنبال این موضوع نرفت.

پایپ‌لاین سبز، الزاماً پایپ‌لاین تحت کنترل نیست. وقت آن رسیده که بررسی کنید واقعاً چه چیزی در پایپ‌لاین شما در حال اجراست.

دسته‌بندی: امنیت

درباره نویسنده

تصویر نویسنده

پوریا فیاضی

پوریا فیاضی هستم؛ فعال در حوزه تکنولوژی، توسعه وب و تولید محتوای دیجیتال. هدف من در این سایت، ارائه مطالب دقیق، قابل اعتماد و کاربردی درباره فناوری، ابزارهای دیجیتال، برنامه‌نویسی و ترندهای روز است؛ محتوایی که هم برای کاربران عمومی قابل فهم باشد و هم برای علاقه‌مندان جدی‌تر دنیای تکنولوژی ارزش داشته باشد.

مطالب پیشنهادی

مشاهده همه

در حال حاضر مطلب پیشنهادی برای نمایش وجود ندارد.

0 نظر

هنوز نظری ثبت نشده است.

ارسال نظر