یک فروشگاه اینترنتی ممکن است کد اختصاصی منظمی داشته باشد، اما برای نمایش صفحه، پردازش فایل و ارتباط با سرویسهای دیگر از قطعات نرمافزاری آماده استفاده کند. امنیت محصول به این قطعات و مسیر دریافت، ساخت و انتشار آنها هم وابسته است. امنیت زنجیرهٔ تأمین نرمافزار یعنی شناخت و کنترل همین مسیر؛ از منبع کد و کتابخانهها تا ابزارهایی که نسخهٔ نهایی را به دست کاربر میرسانند.
این وابستگی به معنای ناامنبودن نرمافزارهای امروزی یا ضرورت نوشتن همهچیز از ابتدا نیست. مسئله این است که اعتماد به یک جزء خارجی باید با شناخت، بررسی و نگهداری همراه باشد. ظاهر سالم برنامه نیز بهتنهایی چیزی دربارهٔ امنیت اجزای درون آن نمیگوید.
زنجیرهٔ تأمین نرمافزار از چه چیزهایی تشکیل میشود؟
در یک محصول فیزیکی، مواد اولیه و قطعات از چند تأمینکننده میآیند. در نرمافزار نیز همهٔ اجزا الزاماً در یک تیم ساخته نمیشوند. «کتابخانه» مجموعهای از قابلیتهای قابل استفادهٔ دوباره است؛ مثلاً برای خواندن فایل یا نمایش نمودار. «بستهٔ نرمافزاری» قالبی برای توزیع کد و اطلاعات مربوط به آن است. بخشی که برنامه برای کارکردن به آن نیاز دارد، وابستگی نامیده میشود.
تیم ممکن است یک کتابخانه را مستقیماً انتخاب کند، اما همان کتابخانه به اجزای دیگری نیاز داشته باشد. این اجزای غیرمستقیم، وابستگیهای گذرا هستند. بنابراین فهرست چند ابزار اصلی لزوماً تمام قطعات محصول را نشان نمیدهد. زنجیره فقط کتابخانهها نیست: مخزن نگهداری کد، حسابهای توسعهدهندگان، ابزار ساخت و سامانهٔ انتشار نیز در آن نقش دارند. راهنمای OWASP دامنهٔ این زنجیره را به اجزای فرایند توسعه گسترش میدهد. [۱]
کتابخانههای نرمافزاری چگونه وارد زندگی روزمره میشوند؟
هنگام بازکردن یک گزارش، جستوجو در فروشگاه یا دیدن نمودار یک برنامه، احتمال دارد چند جزء آماده در پشت صحنه کار کنند. استفاده از آنها به تیم اجازه میدهد روی نیاز خاص محصول تمرکز کند. یک قابلیت رایج، مانند خواندن یک قالب فایل، لازم نیست در هر پروژه دوباره طراحی شود. [۲]
البته کاربر معمولاً نام این اجزا را نمیبیند. برنامهای که روی صفحه یک محصول واحد به نظر میرسد، در عمل حاصل همکاری کد اختصاصی، کتابخانهها و ابزارهای متعدد است. برای نمونه، بخش صدور گزارش میتواند از کتابخانهای جدا استفاده کند، درحالیکه بخش مدیریت کاربران به جزء دیگری وابسته باشد. مسئولیت نگهداری این ترکیب همچنان با تیم محصول است.
آسیبپذیری با آلودگی عمدی چه تفاوتی دارد؟
آسیبپذیری نرمافزاری یک ضعف قابل سوءاستفاده است. ممکن است کتابخانهای معتبر در بررسی ورودی خطایی داشته باشد و در شرایط مشخص، امکان دسترسی نامجاز ایجاد کند. وجود چنین ضعفی لزوماً به معنای قصد مخرب سازنده نیست. برای ارزیابی اثر آن باید نسخه، قابلیت مورد استفاده و شرایط اجرای برنامه بررسی شوند.
در آلودگی عمدی، رفتار مخرب آگاهانه به جزء نرمافزاری اضافه شده است؛ مثلاً کدی که اطلاعات حساس را بدون مجوز منتقل کند. این اتفاق ممکن است در یک بستهٔ جعلی یا در نسخهای دستکاریشده از یک بستهٔ واقعی رخ دهد. بررسی آسیبپذیریهای شناختهشده و بررسی منشأ بسته و دستکارینشدن آن، دو کار مرتبط اما متفاوتاند. خطرهای متنباز نیز فقط به ضعفهای ثبتشده محدود نمیشوند. [۳]
یک جزء آسیبپذیر میتواند مدتها بدون حادثه استفاده شود، اما این سابقه امنیت آینده را تضمین نمیکند. از طرف دیگر، وجود یک هشدار دربارهٔ کتابخانه بهتنهایی اثبات نمیکند که دادههای تمام کاربران سرقت شدهاند. نتیجه باید با شواهد همان محصول و محیط تعیین شود.
مثال فرضی: مشکل از بخش تولید گزارش شروع میشود
فرض کنیم یک سامانهٔ فروش برای ساخت گزارشهای PDF از یک کتابخانه استفاده میکند. کارکنان نام کتابخانه را نمیدانند؛ فقط دکمهٔ «دریافت گزارش» را میبینند. در نسخهای از این جزء، رفتار مخربی وجود دارد که تلاش میکند به اطلاعات قابل دسترس در محیط اجرای خود دست پیدا کند. این مثال ساختگی است و به محصول یا رخداد مشخصی اشاره ندارد.
اگر کتابخانه در بخشی با دسترسی گسترده اجرا شود، پیامد احتمالی میتواند فراتر از تولید گزارش باشد. اگر همان بخش فقط به دادههای ضروری دسترسی داشته باشد و ارتباطات آن محدود و زیر نظر باشد، دامنهٔ خسارت ممکن است کمتر شود. نتیجه به محل اجرا، مجوزها و کنترلهای واقعی بستگی دارد؛ ورود یک کتابخانهٔ آلوده به معنای موفقیت قطعی هر نوع حمله نیست.
در این وضعیت، تعویض کتابخانه بخشی از پاسخ است. تیم باید بررسی کند کدام نسخهٔ محصول از آن استفاده کرده، چه دادههایی در دسترس بوده و آیا نشانهای از فعالیت غیرعادی وجود دارد. مثال نشان میدهد چرا کد اختصاصی سالم، بدون شناخت اجزای بیرونی، تصویر کاملی از امنیت محصول نمیدهد.
حملات زنجیرهٔ تأمین نرمافزار چه مسیری دارند؟
در این حملات، مهاجم ممکن است بهجای حملهٔ مستقیم به هر محصول، یکی از نقاط مورد اعتماد در مسیر توسعه یا توزیع را هدف بگیرد. بستهای با نام گمراهکننده، حساب تصاحبشدهٔ نگهدارنده یا ابزار ساخت ناامن میتواند راه ورود باشد. OWASP سوءاستفاده از وابستگیهای مستقیم و گذرا و حساب نگهدارندگان را در راهنمای امنیت فرایند ساخت بررسی میکند. [۴]
پیامد بسته به موقعیت میتواند دسترسی نامجاز، افشای اطلاعات، تغییر خروجی برنامه یا اختلال در خدمت باشد. همهٔ این نتایج در هر رخداد اتفاق نمیافتند. برای مخاطب عمومی، نکتهٔ اصلی مسیر اعتماد است: دریافت یک جزء از مسیری آشنا جای بررسی نسخه و فرایند انتشار را نمیگیرد.
چه کنترلهایی خطر را کاهش میدهند؟
۱. منشأ اجزا روشن باشد
بستهها باید از منابع رسمی و مورد اعتماد دریافت شوند و هویت و سابقهٔ نگهدارنده بررسی شود. محبوبیت یا تعداد دانلود میتواند اطلاعات زمینهای بدهد، اما تضمین امنیت نیست. انتخاب نسخهٔ مشخص و بررسی تغییرات آن نیز مهم است. دریافت اجزا از منابع معتبر یکی از توصیههای OWASP برای کاهش خطر زنجیرهٔ تأمین است. [۳]
۲. فهرست اجزا به نسخهٔ واقعی محصول وصل شود
تیم باید بداند در هر نسخه چه اجزایی، مستقیم یا غیرمستقیم، وجود دارند. «صورتمواد نرمافزار» یا SBOM فهرستی ساختیافته از اجزاست و نقشهٔ وابستگیها رابطهٔ آنها را نشان میدهد. این اطلاعات برای یافتن محصولات متاثر از یک هشدار کاربرد دارند. فهرست ناقص یا قدیمی ممکن است گمراهکننده باشد؛ داشتن SBOM بهتنهایی اثبات سلامت نرمافزار نیست. [۵]
۳. هشدارها به تصمیم و اقدام منجر شوند
ابزارهای بررسی وابستگی میتوانند ضعفهای شناختهشده را گزارش کنند. نبود هشدار در این ابزارها، نبود آسیبپذیری ناشناخته یا کد مخرب را ثابت نمیکند. بعد از هشدار، لازم است اثر آن بر محصول ارزیابی و مسئول رسیدگی مشخص شود. وقتی نسخهٔ اصلاحشده وجود دارد، تغییر باید در محیط آزمایش بررسی شود؛ بهروزرسانی ناسازگار میتواند کارکرد برنامه را مختل کند. اگر اصلاح فوری ممکن نیست، کاهش دسترسی یا محدودکردن قابلیت درگیر ممکن است اقدام موقت مناسبی باشد، مشروط به ارزیابی فنی. [۱، ۲]
۴. دسترسی ابزارها محدود و تغییرات قابل پیگیری باشند
اصل کمترین دسترسی یعنی هر حساب یا ابزار فقط مجوز لازم برای وظیفهٔ خود را داشته باشد. سامانهٔ ساخت خودکار نباید بیدلیل به همهٔ دادههای عملیاتی دسترسی پیدا کند. تغییر کد و نسخهٔ وابستگیها نیز باید ثبت و بازبینی شود. بررسی امضا یا اطلاعات منشأ میتواند به کنترل اصالت و دستکاری کمک کند، اما بهتنهایی نبود کد مخرب را ثابت نمیکند. [۴، ۵]
۵. رسیدگی به امنیت یک مسئولیت مستمر باشد
کنترلها باید از آغاز توسعه تا نگهداری محصول ادامه پیدا کنند. برای هشدار جدید، نسخهٔ قدیمیِ مستقر و جزء بدون پشتیبانی نیز باید مسئول و مسیر اقدام وجود داشته باشد. چارچوب توسعهٔ امن NIST مجموعهای از رویهها را برای کاهش ضعفها، محدودکردن پیامد سوءاستفاده و رسیدگی به علتهای ایجاد آنها پیشنهاد میکند. این چارچوب جایگزین تصمیم متناسب با محصول نیست. [۶]
کاربر عمومی و تیم فنی از کجا شروع کنند؟
برای کاربر عمومی، توجه به امنیت فقط در انتخاب قابلیت یا ظاهر برنامه خلاصه نمیشود. پرسیدن دربارهٔ روش نگهداری، بهروزرسانی و رسیدگی به مشکلات امنیتی، تصویری مفیدتر از یک وعدهٔ کلی میدهد. پاسخ روشن باید فرایند را توضیح دهد؛ عبارت «کاملاً امن» معیار قابل اتکایی برای مقایسه نیست.
تیم فنی میتواند از یک محصول مشخص شروع کند: نسخهٔ مستقر و اجزای آن را شناسایی کند، وضعیت پشتیبانی را بسنجد و معلوم کند هشدارها به دست چه کسی میرسند. سپس مسیر آزمون و اصلاح و مجوزهای ابزار ساخت را مرور کند. این پیشنهاد آغاز کار است؛ اولویت دقیق به دادهها، دسترسیها و اهمیت همان خدمت بستگی دارد.
امنیت محصول به تمام مسیر ساخت آن وابسته است
امنیت زنجیرهٔ تأمین نرمافزار یعنی اجزای بیرونی و مسیر رسیدن آنها به محصول نهایی، بخشی از مسئولیت مهندسی باشند. استفاده از کتابخانهها میتواند مفید باشد، اما مدیریت وابستگیها نیازمند شناخت نسخهها، بررسی هشدارها و کنترل تغییرات است. هیچ ابزار یا کنترل منفردی امنیت کامل را تضمین نمیکند. پرسش اصلی این است که تیم چقدر این مسیر را میشناسد و هنگام کشف مشکل، چگونه تصمیم میگیرد و اقدام میکند.
