امنیت در CI/CD؛ کنترلهای امنیتی از Commit تا Deployment
پایپلاین CI/CD مسیر انتقال کد از محیط توسعه به محصولی است که در اختیار کاربران قرار میگیرد. این مسیر معمولاً به مخزن کد، ابزارهای ساخت، کتابخانههای نرمافزاری، محیطهای آزمایشی، اطلاعات ورود، سرورها و محیط عملیاتی دسترسی دارد. به همین دلیل، یک ضعف امنیتی در پایپلاین میتواند اثری فراتر از یک خطای معمولی در کد داشته باشد.
امنیت در CI/CD فقط به اجرای یک ابزار اسکن آسیبپذیری محدود نمیشود. کنترل دسترسی به مخزن کد، جلوگیری از افشای Secrets، بررسی وابستگیها، حفاظت از محیط Build، اعتبارسنجی Artifactها و محدودکردن دسترسی به محیط عملیاتی، همگی بخشی از یک پایپلاین امن هستند.
در این مقاله، کنترلهای امنیتی موردنیاز را از لحظه ثبت تغییرات کد یا Commit تا مرحله استقرار یا Deployment بررسی میکنیم.
چرا امنیت پایپلاین CI/CD اهمیت دارد؟
پایپلاین CI/CD به بخشهای مختلف زنجیره تأمین نرمافزار متصل است. مخزن کد، سرویس ساخت، ابزارهای تست، کتابخانههای شخص ثالث، مخزن بستهها، رجیستری کانتینر و محیط عملیاتی همگی ممکن است در این فرایند نقش داشته باشند.
اگر مهاجم به یکی از این بخشها دسترسی پیدا کند، ممکن است کد مخرب را وارد محصول کند، اطلاعات ورود را به دست آورد، خروجی Build را تغییر دهد یا نسخهای غیرمجاز را در محیط عملیاتی مستقر کند. به همین دلیل، امنیت باید در تمام مسیر توسعه و انتشار نرمافزار اعمال شود، نه فقط در مرحله پایانی.
چارچوب NIST Secure Software Development Framework یا SSDF نیز توصیه میکند فعالیتهای توسعه امن در چرخه عمر توسعه نرمافزار ادغام شوند. در این نگاه، امنیت یک مرحله جداگانه پس از تکمیل محصول نیست، بلکه بخشی از طراحی، توسعه، ساخت و انتشار آن است.
کنترلهای امنیتی پیش از Commit
امنیت پایپلاین پیش از ثبت کد آغاز میشود. توسعهدهندگان باید فقط به مخازنی دسترسی داشته باشند که برای انجام وظایف خود به آنها نیاز دارند. استفاده از حسابهای مشترک، دسترسی دائمی مدیر و مجوزهای گسترده، تشخیص مسئول هر تغییر و کنترل اثر یک حساب سرقتشده را دشوار میکند.
دسترسی به مخزن کد باید براساس اصل حداقل دسترسی تعریف شود. فعالسازی احراز هویت چندمرحلهای، حذف حسابهای بلااستفاده و بازبینی دورهای مجوزها نیز احتمال سوءاستفاده از حسابهای توسعهدهندگان را کاهش میدهد.
یکی دیگر از کنترلهای مهم، جلوگیری از ورود اطلاعات حساس به مخزن است. گذرواژهها، کلیدهای API، توکنها، کلیدهای خصوصی و اطلاعات اتصال به پایگاه داده نباید داخل کد یا فایلهای پیکربندی ثبت شوند. بهتر است اسکن Secrets پیش از Commit و دوباره هنگام ارسال تغییرات به مخزن اجرا شود.
اگر یک Secret بهاشتباه وارد مخزن شد، حذف آن از آخرین نسخه کد کافی نیست. مقدار افشاشده باید منقضی یا غیرفعال شود و یک مقدار جدید جایگزین آن شود؛ زیرا نسخه قبلی ممکن است همچنان در تاریخچه مخزن یا گزارشهای پایپلاین باقی مانده باشد.
کنترلهای امنیتی هنگام Push و Pull Request
ارسال مستقیم تغییرات به شاخه اصلی، احتمال ورود کد ناامن یا تغییرات غیرمجاز را افزایش میدهد. شاخههای اصلی مانند main یا release باید محافظت شوند و تغییرات آنها فقط از طریق Pull Request یا Merge Request پذیرفته شود.
بازبینی کد توسط فردی غیر از نویسنده تغییر، یکی از کنترلهای پایه در این مرحله است. برای بخشهای حساس مانند احراز هویت، پرداخت، مدیریت دسترسی یا تنظیمات پایپلاین، میتوان تأیید افراد مشخص را الزامی کرد.
بررسی خودکار نیز باید همزمان با بازبینی انسانی اجرا شود. تحلیل ایستای امنیت کد یا SAST میتواند برخی الگوهای ناامن را پیش از اجرای برنامه شناسایی کند. اسکن مجدد Secrets و بررسی فایلهای تنظیمات نیز از ورود اطلاعات حساس یا پیکربندی ناامن به شاخه اصلی جلوگیری میکند.
فایل تنظیمات پایپلاین باید مانند کد حساس در نظر گرفته شود. اگر هر توسعهدهندهای بتواند بدون بازبینی مراحل Build یا Deployment را تغییر دهد، مهاجم نیز پس از دسترسی به حساب او ممکن است فرمانی برای سرقت اطلاعات یا اجرای کد مخرب به پایپلاین اضافه کند.
کنترلهای امنیتی مرحله Build
در مرحله Build، کد منبع به یک خروجی قابلاستفاده مانند بسته نرمافزاری، فایل اجرایی یا Container Image تبدیل میشود. این مرحله معمولاً به ابزارهای متعدد و گاهی اطلاعات ورود حساس دسترسی دارد؛ بنابراین محیط ساخت باید تا حد امکان ایزوله و محدود باشد.
Runnerها و عاملهای Build نباید دسترسی گسترده و دائمی به شبکه داخلی یا محیط عملیاتی داشته باشند. استفاده از محیطهای موقت برای هر Build باعث میشود فایلها، اطلاعات ورود یا تغییرات یک اجرای قبلی در اجرای بعدی باقی نمانند.
وابستگیهای نرمافزاری نیز باید در این مرحله بررسی شوند. تحلیل ترکیب نرمافزار یا SCA به شناسایی کتابخانههای دارای آسیبپذیری شناختهشده، نسخههای قدیمی و وابستگیهای ناخواسته کمک میکند. نسخه وابستگیها بهتر است بهصورت دقیق مشخص شود تا فرایند ساخت، بدون بررسی، نسخهای متفاوت یا دستکاریشده را دریافت نکند.
استفاده از مخازن معتبر و محدودکردن منابع دریافت بستهها نیز اهمیت دارد. اگر ابزار مدیریت بسته بتواند وابستگیها را از منابع ناشناخته دریافت کند، احتمال حملاتی مانند Dependency Confusion افزایش پیدا میکند.
تولید SBOM یا فهرست اجزای نرمافزار در مرحله Build به سازمان کمک میکند بداند محصول نهایی از چه کتابخانهها و نسخههایی تشکیل شده است. این اطلاعات هنگام انتشار یک آسیبپذیری جدید، تشخیص محصولات تحتتأثیر را سریعتر و دقیقتر میکند.
کنترلهای امنیتی مرحله تست
یک ابزار امنیتی بهتنهایی نمیتواند تمام انواع ضعفها را شناسایی کند. به همین دلیل، کنترلهای امنیتی باید متناسب با فناوری، معماری و ریسک محصول انتخاب شوند.
- SAST برای تحلیل کد منبع و شناسایی برخی الگوهای ناامن پیش از اجرای برنامه استفاده میشود.
- SCA کتابخانهها و وابستگیهای شخص ثالث را از نظر آسیبپذیریهای شناختهشده بررسی میکند.
- DAST برنامه در حال اجرا را از بیرون ارزیابی میکند و برای شناسایی برخی ضعفهای قابلبهرهبرداری مفید است.
- اسکن Container Image میتواند بستههای آسیبپذیر، تنظیمات ناامن و فایلهای حساس موجود در تصویر را شناسایی کند.
- اسکن Infrastructure as Code یا IaC به بررسی تنظیمات زیرساخت پیش از ایجاد منابع ابری یا سرورها کمک میکند.
خروجی این ابزارها باید قابلاستفاده باشد. تولید تعداد زیادی هشدار بدون تعیین مالک، شدت، مهلت اصلاح و امکان ثبت استثنا، بهمرور باعث نادیدهگرفتن نتایج میشود. بهتر است یافتهها براساس اهمیت دارایی، امکان بهرهبرداری، میزان مواجهه و تأثیر کسبوکاری اولویتبندی شوند.
تعریف Security Gate بدون متوقفکردن توسعه
Security Gate شرطی است که اجازه عبور یک تغییر به مرحله بعد را براساس نتیجه کنترلهای امنیتی تعیین میکند. این شرط نباید بهگونهای تعریف شود که هر هشدار کماهمیت، کل فرایند انتشار را متوقف کند.
برای مثال، میتوان استقرار را زمانی متوقف کرد که یک آسیبپذیری بحرانی و قابلبهرهبرداری در یک جزء در معرض اینترنت شناسایی شده باشد. در مقابل، یک ضعف کمخطر در محیط آزمایشی ممکن است ثبت شود و برای اصلاح آن مهلت مشخصی در نظر گرفته شود، بدون آنکه انتشار فوری متوقف شود.
فرایند استثنا نیز باید کنترلشده باشد. هر استثنا باید دلیل، مسئول تأیید، مدت اعتبار و اقدام جبرانی مشخص داشته باشد. استثناهای دائمی و بدون مالک، بهمرور کنترلهای امنیتی پایپلاین را بیاثر میکنند.
حفاظت از Artifact و خروجی ساخت
خروجی Build باید همان فایلی باشد که پس از گذر از کنترلهای امنیتی در محیط مقصد مستقر میشود. ساخت مجدد محصول در مراحل مختلف یا انتقال دستی فایلها، امکان تغییر ناخواسته یا عمدی خروجی را افزایش میدهد.
Artifactها باید در مخزنی کنترلشده نگهداری شوند و دسترسی نوشتن به آنها محدود باشد. ثبت Hash، امضای دیجیتال و اعتبارسنجی امضا پیش از استقرار، به تشخیص تغییر یا جایگزینی غیرمجاز خروجی کمک میکند.
چارچوب SLSA بر حفاظت از زنجیره تأمین نرمافزار، یکپارچگی فرایند ساخت و ثبت اطلاعات منشأ Artifact تأکید دارد. اطلاعات Provenance مشخص میکند یک خروجی در چه محیطی، با چه ورودیهایی و طی چه فرایندی ساخته شده است.
مدیریت امن Secrets در پایپلاین
پایپلاین برای دسترسی به مخازن، سرویسهای ابری، رجیستریها و محیطهای استقرار به اطلاعات ورود نیاز دارد. قرار دادن این اطلاعات در فایل تنظیمات، متغیرهای بدون محافظت یا گزارشهای Build ریسک افشای آنها را افزایش میدهد.
Secrets باید در سامانهای مخصوص نگهداری شوند و فقط هنگام اجرای مرحلهای که به آنها نیاز دارد، در دسترس قرار بگیرند. استفاده از اطلاعات ورود کوتاهعمر نسبت به کلیدهای ثابت و دائمی ارجح است؛ زیرا در صورت افشا، بازه زمانی سوءاستفاده محدودتر خواهد بود.
هر مرحله باید فقط به Secretهای موردنیاز خود دسترسی داشته باشد. برای مثال، مرحله تست نباید اطلاعات ورود به محیط عملیاتی را دریافت کند. همچنین باید از نمایش ناخواسته مقادیر حساس در Logها جلوگیری شود.
راهنمای OWASP Secrets Management نیز بر محدودسازی دسترسی، چرخش اطلاعات حساس و حفاظت از اطلاعات ورود مورد استفاده ابزارهای CI/CD تأکید میکند.
کنترلهای امنیتی مرحله Deployment
استقرار در محیط عملیاتی باید فقط از مسیر رسمی پایپلاین انجام شود. دسترسی مستقیم و گسترده افراد به سرورهای عملیاتی، امکان اجرای تغییرات ثبتنشده و دشوارشدن بررسی رخدادها را افزایش میدهد.
محیطهای توسعه، آزمایش و عملیات باید از یکدیگر جدا باشند. هر محیط باید اطلاعات ورود، سطح دسترسی و سیاستهای مخصوص خود را داشته باشد. استفاده مجدد از یک حساب یا Secret در چند محیط باعث میشود نفوذ به محیط کمحساستر، مسیر دسترسی به محیط عملیاتی را ایجاد کند.
برای استقرارهای حساس میتوان تأیید انسانی، تفکیک وظایف و محدودیت زمانی تعریف کرد. فردی که کد را تغییر داده است، نباید همیشه بتواند بدون بازبینی همان تغییر را مستقیماً در محیط عملیاتی منتشر کند.
پیش از استقرار باید امضا و یکپارچگی Artifact بررسی شود. تنظیمات زیرساخت نیز بهتر است بهصورت IaC مدیریت شوند تا تغییرات آنها قابلبازبینی، آزمایش و ثبت باشند.
فرایند بازگشت یا Rollback باید پیش از رخداد آزمایش شده باشد. اگر انتشار جدید باعث اختلال یا مشکل امنیتی شود، تیم باید بتواند نسخه سالم قبلی را با کمترین تغییر دستی بازگرداند.
پایش پس از استقرار
مسئولیت پایپلاین با پایان Deployment تمام نمیشود. رویدادهای ورود، تغییر تنظیمات پایپلاین، اجرای Jobهای حساس، دریافت Secrets، انتشار Artifact و استقرار در محیط عملیاتی باید ثبت و پایش شوند.
گزارشها باید بهاندازهای نگهداری شوند که امکان بررسی رخداد وجود داشته باشد، اما نباید حاوی گذرواژه، توکن یا اطلاعات حساس باشند. هشدارهای امنیتی نیز باید به رفتارهای مهم مانند اجرای غیرمعمول پایپلاین، تغییر مجوزها، غیرفعالشدن کنترلها یا استقرار خارج از روال رسمی توجه کنند.
پایش وضعیت نرمافزار پس از انتشار نیز اهمیت دارد. افزایش خطاها، تغییر غیرعادی ترافیک، رفتار غیرمنتظره سرویسها و شکست کنترلهای امنیتی ممکن است نشانه یک استقرار معیوب یا رخداد امنیتی باشند.
چکلیست امنیت CI/CD از Commit تا Deployment
- دسترسی مخازن و ابزارهای پایپلاین براساس اصل حداقل دسترسی تنظیم شده باشد.
- احراز هویت چندمرحلهای برای حسابهای حساس فعال باشد.
- شاخههای اصلی محافظت شوند و تغییرات فقط پس از بازبینی ادغام شوند.
- اسکن Secrets پیش و پس از ثبت تغییرات اجرا شود.
- تغییر فایلهای پایپلاین نیازمند بازبینی و تأیید باشد.
- SAST، SCA و سایر تستها براساس ریسک محصول انتخاب شوند.
- وابستگیها از منابع معتبر دریافت و نسخه آنها کنترل شود.
- محیطهای Build ایزوله، محدود و ترجیحاً موقت باشند.
- SBOM برای نسخههای قابلانتشار تولید و نگهداری شود.
- Artifactها امضا و پیش از استقرار اعتبارسنجی شوند.
- اطلاعات ورود در سامانه مدیریت Secrets نگهداری شوند.
- دسترسی مستقیم به محیط عملیاتی محدود باشد.
- استقرارهای حساس به تأیید و تفکیک وظایف نیاز داشته باشند.
- فرایند Rollback تعریف و آزمایش شده باشد.
- رویدادهای امنیتی پایپلاین ثبت، پایش و به تیم مسئول ارجاع داده شوند.
اشتباهات رایج در امنسازی پایپلاین
یکی از اشتباهات رایج، اضافهکردن چند ابزار اسکن بدون تعریف فرایند رسیدگی به نتایج است. اگر مالک هر یافته، معیار اولویتبندی و مهلت اصلاح مشخص نباشد، هشدارها بهمرور نادیده گرفته میشوند.
اشتباه دیگر، دادن دسترسی گسترده به Runnerها، توسعهدهندگان یا حسابهای سرویس است. این دسترسیها ممکن است اجرای پایپلاین را سادهتر کنند، اما در صورت سرقت حساب یا اجرای کد مخرب، دامنه آسیب را افزایش میدهند.
ذخیره Secrets در مخزن، استفاده از کلیدهای دائمی، غیرفعالکردن کنترلها برای انتشار سریعتر و اعتماد بدون اعتبارسنجی به بستهها و Artifactهای دریافتی نیز از خطاهایی هستند که امنیت کل زنجیره انتشار را تضعیف میکنند.
فهرست OWASP Top 10 CI/CD Security Risks ریسکهایی مانند کنترل ناکافی جریان، مدیریت نامناسب هویت و دسترسی، سوءاستفاده از زنجیره وابستگیها، بهداشت ضعیف اطلاعات ورود، اعتبارسنجی ناکافی Artifact و کمبود ثبت رویداد و دیدپذیری را بررسی میکند.
جمعبندی
امنیت در CI/CD با نصب یک ابزار یا اجرای یک اسکن تکمیل نمیشود. پایپلاین امن به مجموعهای از کنترلهای هماهنگ نیاز دارد که از دسترسی توسعهدهنده و ثبت Commit آغاز میشوند و تا ساخت، آزمایش، حفاظت از Artifact، استقرار و پایش محیط عملیاتی ادامه پیدا میکنند.
نقطه شروع مناسب، ترسیم مسیر فعلی انتشار نرمافزار و شناسایی دسترسیها، اطلاعات حساس، ابزارها و نقاطی است که در آنها امکان تغییر کد یا خروجی وجود دارد. پس از آن، میتوان کنترلها را براساس ریسک و اهمیت هر مرحله اولویتبندی کرد.
اگر سازمان شما برای ارزیابی امنیت چرخه توسعه، طراحی کنترلهای پایپلاین یا پیادهسازی تدریجی DevSecOps به مسیر اجرایی مشخصی نیاز دارد، میتوانید با خدمات امنیت نرمافزار و DevSecOps امنآپس آشنا شوید.