حمله هکری به NPM یکی از اخرین اخبار امنیتی مربوط به ارز های دیجیتال بود که در روز های اخیر منتشر شد ، وابستگی روزافزون توسعهدهندگان به کتابخانهها و بستههای منبعباز در دنیای برنامهنویسی، فرصتهای بینظیری برای تسریع و تسهیل فرآیند توسعه فراهم کرده است. پلتفرمهایی مانند NPM (Node Package Manager) با ارائه دسترسی به هزاران پکیج آماده، این روند را به شدت محبوب ساختهاند. با این حال، همین وابستگی میتواند به یک نقطه ضعف امنیتی مهم تبدیل شود : حملات زنجیره تأمین نرمافزار (Software Supply Chain Attacks).
در سالهای اخیر، افزایش نگرانکنندهای در این نوع حملات مشاهده شده است. مهاجمان با نفوذ به حسابهای توسعهدهندگان یا نگهدارندگان پکیجها، کدهای مخرب را در بستههایی که میلیونها بار دانلود میشوند، جاسازی میکنند.
در یکی از بزرگترین حملات اخیر در تاریخ NPM، بدافزاری از طریق چند بسته منتشر شد و میلیاردها بار دانلود شد که نشاندهنده ابعاد و خطر جدی این نوع حملات است. این حادثه، بار دیگر اهمیت تأیید و بررسی امنیتی وابستگیها را به ما یادآوری میکند.
جزئیات حمله
این حمله با نفوذ به حساب کاربری یکی از توسعهدهندگان معتبر NPM آغاز شد. مهاجم پس از دستیابی به این حساب، نسخههای مخربی از چندین بسته محبوب و پرکاربرد را منتشر کرد.
این پکیجها شامل موارد زیر بودند:
-
@phobal/cli color-consolestripercore-utils-
color-range
و چندین بسته دیگر که به صورت مستقیم یا به عنوان وابستگی، در پروژههای متعددی استفاده میشدند. این بستههای آلوده، میلیاردها بار توسط کاربران مختلف دانلود شده و بدین ترتیب، بدافزار به صورت گستردهای در کل اکوسیستم جاوااسکریپت پخش شد. این رویداد، ابعاد وسیع و خطرناک حملات زنجیره تأمین نرمافزار را به وضوح نشان میدهد.

اهداف حمله چه بودند؟
هدف اصلی این حمله به طور خاص، سرقت اطلاعات مالی و رمزارزها بود. این حمله دو هدف کلیدی را دنبال میکرد:
- سرقت اطلاعات کیفپولهای رمزارز: به طور ویژه، اطلاعات کیفپولهای اتریوم و بیتکوین مورد هدف قرار گرفتند.
- تغییر آدرس کیفپول: بدافزار میتوانست آدرس کیفپول قربانی را در مرورگر تغییر دهد. به این ترتیب، هرگونه تراکنش رمزارزی به جای آدرس اصلی، به آدرس تحت کنترل مهاجم هدایت میشد.
این نوع حملات، به ویژه برای کاربران دیفای (DeFi) و اپلیکیشنهای رمزارزی، خطرات جدی به دنبال دارند؛ چرا که میتوانند مستقیماً به سرقت داراییهای دیجیتال آنها منجر شوند.
آغاز ماجرا : یک خطای ساده در CI/CD
این حمله زمانی کشف شد که یکی از توسعهدهندگان، حین فرآیند ساخت (Build) پروژه خود در محیط CI/CD، با خطای غیرمنتظرهای مواجه شد:
ReferenceError: fetch is not defined
این خطا در مرحله اجرای تستهای خودکار ظاهر شد. پس از بررسی دقیقتر، مشخص شد که مشکل از نسخه بهروزرسانیشده یکی از بستههای پروژه است. با پیگیری بیشتر، توسعهدهندگان یک فایل مخرب را در مسیر وابستگیها پیدا کردند.
کد زیر، بخشی از کد مبهمشده (obfuscated) بود که توجه را جلب نمیکرد، اما در حقیقت، هدف اصلی آن اجرای یک ماژول رمزگذاریشده برای دسترسی به اطلاعات حساس کاربران بود:
JavaScript
const buf = Buffer.from(“…”)
eval(buf.toString())
این کشف اتفاقی، به عنوان یک نمونه عینی از اهمیت نظارت مداوم بر وابستگیها و اسکن امنیتی خودکار در فرآیندهای توسعه نرمافزار محسوب میشود.
بررسی فنی : بدافزاری در دو مرحله
مهاجمان برای اجرای این حمله، از یک ساختار دو مرحلهای بهره بردند:
مرحله اول: بررسی محیط
در این مرحله، کدی ساده اجرا میشود تا بررسی کند آیا محیط فعلی به یک کیفپول رمزارز دسترسی دارد یا خیر. این کد به طور خاص، به دنبال وجود شیء ethereum و متد request در مرورگر میگردد:
JavaScript
if (window.ethereum && ethereum.request) { ethereum.request({ method: ‘eth_accounts’ }).then(…)}
این بخش از کد به عنوان یک “اسکیمر” عمل میکند و تنها زمانی فعال میشود که یک کیفپول مانند MetaMask در مرورگر کاربر نصب شده باشد.
مرحله دوم: استخراج و جایگزینی
پس از یافتن یک حساب فعال، بدافزار به سرعت وارد عمل میشود تا اهداف اصلی خود را محقق سازد. در این مرحله، کدهای مخرب وظایف زیر را انجام میدهند:
- استخراج آدرس کیفپول فعال: بدافزار ابتدا آدرس کیفپول فعال قربانی را شناسایی و استخراج میکند.
- نظارت بر تراکنشها: کد مخرب به صورت مداوم بر تمام تراکنشهای ورودی و خروجی در حال انجام، نظارت میکند.
- جایگزینی آدرس مقصد: در لحظه انجام تراکنش، بدافزار آدرس کیفپول مقصد را با آدرس تحت کنترل مهاجم جایگزین میکند.
با این روش، تراکنشها به جای کیفپول اصلی مقصد، به آدرس مهاجم هدایت شده و داراییهای دیجیتال قربانی به سرقت میروند. این شیوه، نشاندهنده پیچیدگی و هدفمندی بالای این نوع حملات است.

تکنیکهای کلیدی استفاده شده
مهاجمان برای سرقت رمزارزها، از روشهای پیچیده و چندوجهی استفاده کردند که شامل موارد زیر است:
1.جایگزینی غیرفعال آدرس (Passive Address Swapping)
بدافزار به صورت مداوم، آدرس مقصد تراکنشها را زیر نظر داشت. اگر آدرس مقصد با آدرس مهاجم یکسان نبود، آن را با آدرس مهاجم جایگزین میکرد و تراکنش را دوباره ارسال مینمود. این روش، بدون اینکه کاربر متوجه تغییری شود، سرمایه او را به کیفپول مهاجم منتقل میکرد.
2.ربودن تراکنش (Transaction Hijacking)
در این روش، بدافزار حتی پس از اینکه کاربر تراکنش را امضا میکرد (مثلاً با استفاده از ethers.sendTransaction)، فعال میشد. کد مخرب، امضای کاربر را نگه میداشت، محتویات تراکنش را تغییر میداد (آدرس مقصد را عوض میکرد) و سپس با استفاده از همان امضای اصلی، تراکنش را دوباره ارسال میکرد. این کار باعث میشد که حتی پس از تأیید نهایی کاربر، تراکنش به مقصد اشتباهی فرستاده شود.
3.ربودن حافظه کلیپبورد (Clipboard Hijacking)
در صورتی که هیچ کیفپولی در مرورگر فعال نبود، بدافزار همچنان در پسزمینه فعالیت میکرد. این بدافزار، حافظه کلیپبورد کاربر را تحت نظر میگرفت و منتظر میماند تا کاربر یک آدرس کیفپول را کپی کند. به محض اینکه کاربر آدرس را Paste میکرد، بدافزار آدرس کپیشده را با آدرس مهاجم جایگزین مینمود. این روش، حتی بدون نیاز به یک کیفپول فعال در مرورگر، میتوانست باعث سرقت داراییها شود.
تأثیرات حمله: اکوسیستم در معرض تهدید
بستههایی که در این حمله درگیر بودند، در پروژههای متعددی استفاده میشدند. برخی از آنها بیش از 300 میلیون بار دانلود شده بودند. لیست برخی از بستههای آلوده:
| نام بسته | تعداد دانلود (هفتگی) |
| color-console | 290 میلیون |
| strip-ansi | 385 میلیون |
| color-range | 19 میلیون |
| core-utils | 47 میلیون |
| simple-color | 35 میلیون |
با توجه به گستردگی استفاده، بسیاری از پروژهها بدون آنکه بدانند، به صورت غیرمستقیم به این بدافزار آلوده شده بودند.

آدرسهای استفاده شده توسط مهاجم
یکی از آدرسهای کیف پول اتریومی مهاجم به شرح زیر است:
0xFc4a4858bafef54D1b1d7697bfb5c52F4c166976
این آدرس در تراکنشهای متعددی دیده شده و میتوان آن را در Etherscan پیگیری کرد.
چگونه از پروژه خود محافظت کنیم؟
در صورت استفاده از هر یک از بستههای آلوده، لازم است فوراً اقدامات زیر انجام شود:
- بهروزرسانی فوری
نسخههای جدید تمام بستههای آلوده منتشر شدهاند و کد مخرب حذف شده است. در اولین فرصت باید به نسخههای جدید مهاجرت کنید. - بررسی فایل package-lock.json
اطمینان حاصل کنید که نسخه دقیق پکیجهای مورد استفاده با نسخههای سالم هماهنگ باشند. - استفاده از resolutions در package.json
اگر پروژه شما از بستههایی استفاده میکند که به صورت غیرمستقیم به نسخههای آلوده وابستهاند، میتوانید با استفاده از resolutions نسخه ایمن را اجباری کنید:
{
“name”: “your-project”,
“version”: “1.0.0”,
“resolutions”: {
“color-console”: “1.4.1”,
“core-utils”: “2.1.7”,
“strip-ansi”: “6.0.1”
}
}
- قفل کردن نسخهها (Version Pinning)
از بهروزرسانی خودکار وابستگیها در محیط تولید جلوگیری کنید مگر آنکه به صورت دستی بررسی شوند. - استفاده از ابزارهای امنیتی مانند Snyk یا Dependabot
این ابزارها میتوانند آسیبپذیریها را شناسایی و گزارش کنند.

نتیجه گیری حمله هکری به NPM
نگرانکننده این است که مهاجمان، به جای تلاش برای نفوذ مستقیم به تکتک کاربران، با سوءاستفاده از اعتماد در اکوسیستم NPM و اعتماد توسعهدهندگان به پکیجهای منبعباز، موفق شدند بدافزار خود را در مقیاس وسیع توزیع کنند.
این حمله بار دیگر نشان داد که امنیت نرم افزار تنها به کد ما محدود نمیشود، بلکه به تمام وابستگیها و زنجیره تأمین آن نیز بستگی دارد. این رویداد، هشداری جدی برای جامعه توسعهدهندگان است تا در انتخاب و استفاده از بستههای شخص ثالث دقت بیشتری به خرج دهند.
جزئیات بیشتر در مورد این حمله را میتوایند در مقاله Anatomy of a Billion-Download NPM Supply-Chain Attack در سایت Substack مطالعه کنید.
درسهایی که از این حمله آموختیم
برای کاهش ریسک حملات زنجیره تأمین، پیروی از توصیههای زیر ضروری است:
-
- بررسی دقیق وابستگیها: هر وابستگی، حتی آنهایی که در ظاهر بیخطر به نظر میرسند، میتوانند دروازهای برای نفوذ مهاجمان باشند.
- بازبینی تغییرات (Changelog): قبل از بهروزرسانی هر بسته، بررسی دقیق لیست تغییرات (changelog) آن به شدت توصیه میشود. این کار میتواند به شناسایی تغییرات مشکوک و ناخواسته در کد کمک کند.
- تأمین امنیت حساب کاربری: حفظ امنیت حسابهای توسعهدهندگان در پلتفرمهایی مانند NPM از طریق استفاده از احراز هویت دومرحلهای (2FA) و رمزهای عبور قوی، حیاتی است.
- استفاده از ابزارهای امنیتی خودکار: بهرهگیری از ابزارهای اسکن خودکار امنیتی میتواند به شکل چشمگیری خطرات را کاهش دهد. این ابزارها به صورت مداوم، وابستگیها را برای یافتن آسیبپذیریها و کدهای مخرب بررسی میکنند.

4 Responses
اینطور که نوشتهاید بدافزار آدرس کیفپول رو تغییر میداد یعنی اگر کسی بستههای آلوده رو نصب کرده باشه
تراکنشهاش میره سمت مهاجم؟ خیلی نگرانکنندهست
نیما جان، بله؛ سازوکار این نوع بدافزارها میتونه آدرس مقصد در فرایند ارسال رمزارز رو تغییر بده. اگر شک دارید که از پکیجهای مشکوک استفاده کردید، توصیه میکنیم کلیدها یا آدرسهای حساس رو بلافاصله بررسی و در صورت لزوم از کیفپول جدید استفاده کنید.
سلام. مقاله خیلی هشداردهندهای بود. من یک پروژه قدیمی جاوا اسکریپت دارم که چندین ماهه آپدیتش نکردم. چطور میتونم بفهمم که آیا در زمان نصب اولیه، یکی از بستههای آلوده (مثل color-console که اشاره کردید) رو نصب کرده بودم یا نه؟ آیا ابزار خاصی برای اسکن پروژههای محلی وجود داره؟
آرش عزیز، نگرانی شما کاملاً بهجاست. برای بررسی پروژههای قدیمی، بهترین راهکار استفاده از ابزارهای مدیریت آسیبپذیری است. ابزارهایی مانند npm audit میتوانند وابستگیهای شما را با دیتابیس آسیبپذیریها مقایسه کنند. همچنین، پلتفرمهای تخصصی اسکن مانند Snyk یا Dependabot (گیتهاب) میتوانند به طور خودکار پروژهتان را اسکن کرده و نسخههای آلوده را شناسایی کنند.