این هفته یک مشتری جعلی یک مخزن مخرب GitHub را به صندوق ورودی من فرستاد و صرفاً با اجرای اسکریپت اولیه، دو روز از کار من از بین رفت و تمام رمزهای عبوری که در مرورگرم ذخیره کرده بودم، لو رفت.

این «مشتری» یک موقعیت شغلی مهندس ارشد با حقوق بالا منتشر کرد، سریع پیام داد و یک مخزن (repo) بسیار حرفه‌ای فرستاد. درخواست ساده بود: کلون کردن، اجرای npm run dev و ارسال یک اسکرین‌شات برای اثبات اینکه دمو کار می‌کند—بدون قرارداد و بدون بررسی سوابق. به محض اینکه سرور توسعه (dev server) شروع به کار کرد، کدی مخفی در یک فایل پیکربندی با یک سرور فرمان و کنترل (C2) ارتباط برقرار کرد، یک محموله (payload) مرحله دوم را دریافت کرد و شروع به استخراج اطلاعات کاربری (credentials) از ماشین محلی کرد.

نحوه وقوع حمله

محموله مخرب در فایل postcss.config.js قرار داشت؛ فایلی که اکثر توسعه‌دهندگان به سرعت از کنار آن می‌گذرند، زیرا معمولاً شامل چند قانون ساده برای پردازش CSS است. در این مورد، مهاجم یک خط جاوااسکریپت مبهم (obfuscated) را در انتهای سمت راست یک دستور قانونی اضافه کرده بود و با استفاده از فاصله‌ها (spaces) آن را طوری تنظیم کرده بود که با بقیه کد هم‌خوانی داشته باشد. وقتی دستور npm run dev خط لوله (pipeline) PostCSS را اجرا کرد، آن خط مخفی بدون اینکه کسی متوجه شود، اجرا شد.

بدافزار سه مرحله را با سرعت پشت سر هم انجام داد:

  • ارتباط با C2 – یک اتصال شبکه به سروری که تحت کنترل مهاجم بود برقرار کرد و میزبان آلوده شده را معرفی نمود.
  • دانلود مرحله دوم – کدهای اضافی را که حاوی منطق اصلی استخراج داده‌ها (data-exfiltration) بود، دریافت کرد.
  • سرقت اطلاعات کاربری مرورگر – در macOS، این کد کلید Chrome Safe Storage را که در keychain سیستم ذخیره شده بود، استعلام گرفت. اگر کاربر درخواست keychain را تأیید می‌کرد، مهاجم تمام رمزهای عبور ذخیره شده در Chrome را جمع‌آوری می‌کرد.

فراتر از سرقت مستقیم، این محموله خود را در چندین ابزار رایج توسعه‌دهندگان—مانند VS Code، npm و Discord—کاشت تا با هر بار اجرای مجدد آن برنامه‌ها در آینده، کد مخرب دوباره فعال شود. یک ریبوت ساده هم عفونت را از بین نمی‌برد؛ اولین npm install بعدی یا باز کردن مجدد ویرایشگر، درِ پشتی (backdoor) را دوباره زنده می‌کرد.

نشانه‌های خطر که اغلب نادیده گرفته می‌شوند

  • درخواست برای اجرای کد قبل از امضای هرگونه قرارداد. فرآیندهای استخدام قانونی معمولاً پیش از اشتراک‌گذاری هرگونه کار اختصاصی، شامل یک توافق رسمی هستند.
  • فایل‌های فشرده که خود را به عنوان «خلاصه پروژه» جا می‌زنند. آرشیوهای Zip یا RAR می‌توانند اسکریپت‌های اجرایی یا باینری‌های مخرب را پنهان کنند.
  • درخواست برای آدرس ایمیل شخصی جهت «دور زدن فیلترهای پلتفرم». این ترفند باعث می‌شود گفتگو از پلتفرم محافظت‌شده‌ای که امکان گزارش سوءاستفاده در آن وجود دارد، خارج شود.
  • شرح وظایفی که از کاندیدا می‌خواهند یک کیف پول کریپتو را شارژ کند یا توکن‌های تست بخرد. چنین درخواست‌هایی برای کارهای توسعه واقعی غیرمعمول است.

گام‌های عملی برای حفظ امنیت

  1. هرگز کد یک غریبه را بدون بازرسی اجرا نکنید. مخزن را در حالت فقط‌خواندنی (مثلاً از طریق نمای raw فایل در GitHub) باز کنید و تمام اسکریپت‌ها، به‌ویژه فایل‌های پیکربندی و ورودی‌های scripts در package.json را بررسی کنید.
  2. با تمام پیوست‌ها مانند متن ساده برخورد کنید. اگر یک فایل zip ارسال شد، آن را در یک محیط ایزوله (sandbox) استخراج کرده و قبل از باز کردن هر چیزی، محتویات آن را بررسی کنید.
  3. به جای ذخیره‌سازی در مرورگر، از یک مدیریت‌کننده رمز عبور اختصاصی استفاده کنید. حتی اگر keychain مرورگر لو برود، گاوصندوق مدیریت‌کننده رمز عبور ایزوله باقی می‌ماند.
  4. کدهای غیرقابل اعتماد را در یک ماشین مجازی یا کانتینر ایزوله بدون دسترسی به شبکه اجرا کنید. این کار مانع از توانایی مهاجم برای دسترسی به سرور C2 می‌شود.
  5. تأیید دو مرحله‌ای (2FA) را در تمام حساب‌ها فعال کنید. اگر رمز عبوری دزدیده شود، عامل دوم از ورودهای غیرمجاز جلوگیری می‌کند.
  6. ابزارهای توسعه را به‌روز نگه دارید و در صورت امکان، بررسی خودکار سلامت (integrity checks) را فعال کنید. برخی از ویرایشگرها اکنون در صورت تغییر غیرمنتظره فایل‌های اصلی، هشدار می‌دهند.

اگر شک دارید که کد مخربی را اجرا کرده‌اید، فرض کنید سیستم شما هک شده است. از داده‌های ضروری نسخه پشتیبان تهیه کنید، درایو را پاک کنید و سیستم‌عامل را دوباره نصب کنید. یک ریبوت ساده، مکانیزم پایداری (persistence mechanism) را که فایل‌های برنامه‌های رایج را بازنویسی می‌کند، از بین نمی‌برد.

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