در یک حمله زنجیره تأمین که از طریق فیشینگ هدفمند و سرقت اطلاعات کاربری صورت گرفته، چند پکیج JavaScript محبوب، دستکاری و به دراپر بدافزار تبدیل شدند.
پکیج eslint-config-prettier، که بهتنهایی بیش از ۳۰ میلیون بار در هفته دانلود میشود، پس از اینکه مدیر آن هدف یک حمله فیشینگ قرار گرفت، آلوده شد. سایر پکیجهای مرتبط با همین مدیر، از جمله eslint-plugin-prettier، synckit، @pkgr/core و napi-postinstall نیز در این حمله مورد هدف قرار گرفتند. مهاجمان با استفاده از اطلاعات کاربری بهسرقترفته، نسخههایی غیرمجاز از این پکیجها را با کد مخرب منتشر کردند که هدف آنها آلوده کردن دستگاههای ویندوزی بود.
جزئیات حمله به پکیج JavaScript
در تاریخ ۱۸ ژوئیه، توسعهدهندگان متوجه رفتارهای مشکوکی پس از نصب نسخههای خاصی از eslint-config-prettier شدند (نسخههای 8.10.1، 9.1.1، 10.1.6، 10.1.7). این نسخهها در رجیستری npm منتشر شده بودند؛ اما در مخزن GitHub هیچ تغییری که این انتشارها را توجیه کند، ثبت نشده بود؛ موضوعی که بهسرعت باعث شک کاربران متنباز شد.
کتابخانههایی مانند eslint-config-prettier و eslint-plugin-prettier به توسعهدهندگان کمک میکنند تا از نظر ظاهری، قوانین فرمتدهی کدها را در کنار ESLint و Prettier بهصورت هماهنگ و بدون تداخل اجرا کنند. یکی از توسعهدهندگان به نام Dasa Paddock موضوع را در GitHub مطرح کرد و بقیه اعضای جامعه نیز به سرعت به بحث پیوستند. مدتی بعد، مدیر اصلی این پکیجها، یعنی JounQin، تأیید کرد که هدف حمله فیشینگ قرار گرفته و مهاجم از طریق توکن npm او موفق به انتشار نسخههای آلوده شده است.
ایمیل فیشینگ بهگونهای طراحی شده بود که از نظر ظاهری به آدرس رسمی support@npmjs.com شباهت داشت؛ اما در واقع کاربر را به دامنهای جعلی به آدرس npnjs[.]com هدایت میکرد.

نحوه انتشار بدافزار
در پکیجهای آلوده، یک اسکریپت postinstall بهنام install.js بهصورت خودکار هنگام نصب اجرا میشود. در این فایل، تابعی با نام فریبنده logDiskSpace() وجود دارد که برخلاف نامش، کاری با فضای دیسک ندارد. این تابع تلاش میکند با استفاده از rundll32(یک فرآیند سیستمی ویندوز)، فایل node-gyp.dll را که در داخل پکیج وجود دارد، اجرا کند.

در زمان انتشار خبر، این فایل DLL بهعنوان تروجان شناخته شده و در سایت VirusTotal امتیاز تشخیص ۱۹ از ۷۲ را دارد؛ به این معنا که بسیاری از آنتیویروسها هنوز آن را شناسایی نمیکنند.
حمله مشابه دیگر
حساب X با نام MalwareUtkonos گزارش داد که پکیج got-fetch (توسعه دادهشده توسط فردی دیگر) نیز به شکل مشابهی هدف حمله قرار گرفته است. در این حمله نیز از یک فایل DLL مشابه با نام crashreporter.dll استفاده شده که شباهتهایی به node-gyp.dll موجود در پکیجهای آلوده دیگر دارد؛ موضوعی که احتمال نقش داشتن همان مهاجم در هر دو حمله را تقویت میکند.

توسعهدهنده پکیج got-fetch نیز مخزن GitHub این پکیج را بلافاصله بایگانی کرده و تمام نسخههای منتشرشده در npm را، حتی نسخههای سالم، منسوخ اعلام کرده و از کاربران خواسته بهجای آن از fetch داخلی nodejs استفاده کنند.
چه کار باید بکنید؟
بههیچوجه نسخههای زیر را نصب نکنید:
- eslint-config-prettier: نسخههای10.1، 9.1.1، 10.1.6، 10.1.7
- eslint-plugin-prettier: نسخههای2.2، 4.2.3
- synckit: نسخه11.9
- @pkgr/core: نسخه2.8
- napi-postinstall: نسخه3.1
- got-fetch: نسخههای1.11، 5.1.12
فایلهای قفل پروژه مانند package-lock.json، pnpm-lock.yaml، yarn.lock یا bun.lock را بررسی کرده و اگر این نسخهها در آنها وجود دارند، اقدامات لازم برای حذف آنها را انجام دهید. اگر بعد از ۱۸ ژوئیه build منتشر کردهاید، لاگهای CI و محیطهای اجرایی خود را، بهویژه در سیستمهای ویندوزی، بررسی کنید تا علائمی از نفوذ یا اجرای کد مخرب را بیابید. در صورت وجود هرگونه secrets در فرایند ساخت، پیشنهاد میشود آنها را نیز تغییر دهید.
مدیر پکیجها تمامی نسخههای آسیبدیده را در npm به عنوان «deprecated» علامتگذاری کرده است. همچنین یک کاربر GitHub هشدار داده که ممکن است سایر پکیجهای منتشرشده توسط این توسعهدهنده نیز مورد دستکاری قرار گرفته باشند و باید بررسی شوند.

ارتباط میان حملات پیشین
این حمله بخشی از موجی از حملات مهندسی اجتماعی است که اخیرا توسعهدهندگان پکیجهای پرکاربرد را هدف قرار داده است. در ماه مارس، بیش از ده پکیج npm دچار نفوذ شدند و به ابزار سرقت اطلاعات تبدیل گشتند. ماه گذشته نیز، ۱۷ پکیج از Gluestack که هفتهای بیش از یک میلیون بار دانلود میشدند، برای انتشار بدافزار RAT مورد سوءاستفاده قرار گرفتند.
از آنجا که اکوسیستم متنباز مبتنی بر اعتماد است، چنین حوادثی ضعفهای زنجیره تأمین و لزوم امنیت بیشتر برای مدیران پکیجها را برجسته میکند. تنها یک کلیک اشتباه میتواند میلیونها کاربر را در معرض خطر قرار دهد.