اسکن بدافزار npm هنگام انتشار؛ قانون جدید package.json و DISCLOSURE

اسکن بدافزار npm هنگام انتشار؛ قانون جدید package.json و DISCLOSURE

از 28 ژوئیه 2026، انتشار روی npm دیگر لزوماً به معنی قابل نصب شدن فوری نسخه نیست. پکیج تازه ابتدا اسکن می شود و براساس نتیجه می تواند عادی منتشر شود، برای بررسی دستی نگه داشته شود یا Block شود. هم زمان Maintainer ابزارهای Dual-use باید Metadata جدید در package.json، فایل DISCLOSURE و مسیر انتشار دارای احراز هویت دومرحله ای داشته باشد. این تغییر هم Pipeline انتشار و هم مسئولیت امنیتی Maintainer را عوض می کند.

npm دقیقاً چه تغییری داده است؟

هر نسخه تازه قبل از آنکه برای npm install در دسترس قرار گیرد، وارد اسکن خودکار بدافزار می شود. نتیجه سه حالت دارد: انتشار عادی، Hold برای بررسی دستی یا Block. این اسکن بین دستور publish و Availability فاصله ایجاد می کند. npm زمان معمول را حدود پنج دقیقه اعلام کرده، اما زمان پیک، اندازه پکیج یا محتوای پیچیده می تواند آن را به 15 دقیقه یا بیشتر برساند. این عدد تعهد سرویس نیست و Pipeline باید انعطاف داشته باشد.

تا زمانی که اسکن Pending است، npm dist-tag همچنان کار می کند، اما عملیات وابسته به نسخه Available مانند deprecate و unpublish انجام نمی شود. بنابراین Scriptی که بلافاصله پس از publish نسخه را نصب، Deprecated یا Promote می کند باید بازطراحی شود. معیار پایان Release باید قابل نصب شدن نسخه از Registry باشد، نه فقط Exit Code موفق npm publish.

چرا اسکن در زمان انتشار مهم است؟

پکیج Registry بخش حساسی از زنجیره تأمین است. Dependency ممکن است مستقیم یا Transitive وارد هزاران پروژه شود و Script نصب آن در CI، لپ تاپ توسعه دهنده یا سرور اجرا شود. تشخیص بدافزار پیش از Available شدن، فرصت توزیع را کاهش می دهد. این کنترل جای Review و Security Pipeline Maintainer را نمی گیرد، اما یک لایه مرکزی در Registry اضافه می کند.

اسکن کامل و بدون خطا نیست. npm نیز می گوید بدافزاری را Block می کند که بتواند تشخیص دهد و پوشش را بهبود می دهد. Package مبهم یا Dual-use می تواند False Positive ایجاد کند و برای Review نگه داشته شود. تیم Release باید تأخیر و Appeal را بخشی از فرایند بداند، نه خرابی غیرمنتظره سرویس.

Pipeline انتشار چگونه باید تغییر کند؟

Pipeline قدیمی معمولاً Build، Test، npm publish و سپس Integration Test نسخه Registry را پشت سرهم اجرا می کند. اکنون میان Publish و Test باید مرحله انتظار وجود داشته باشد. Polling با Backoff انجام دهید، Timeout منطقی بگذارید و وضعیت Pending را از Failure جدا کنید. Retry دوباره publish برای همان Version مناسب نیست، چون Version npm تکرارپذیر نیست و می تواند وضعیت را پیچیده کند.

Tag Release در GitHub و اعلان کاربران را پس از تأیید Availability انجام دهید. اگر Monorepo چند Package منتشر می کند، وابستگی داخلی ترتیب دارد و Package دوم ممکن است قبل از Available شدن اولی Fail شود. Staged Release یا ترتیب Polling لازم است. همچنین Metric مدت اسکن را ثبت کنید تا Timeout براساس داده واقعی تنظیم شود.

Dual-use Content چیست؟

Dual-use به قابلیتی گفته می شود که استفاده مشروع امنیتی یا فنی دارد، اما رفتارش می تواند شبیه ابزار مخرب باشد. Scanner شبکه، Password Audit، Exploit Lab، Packet Capture، Remote Administration و ابزار Obfuscation نمونه هایی هستند که Context استفاده تعیین کننده است. Declaration به npm کمک می کند ابزار مشروع را از پکیج مخرب بهتر تفکیک کند؛ اما Declaration مجوز بدافزار نیست.

Maintainer باید با قضاوت مسئولانه تعیین کند Package در این دسته قرار می گیرد یا نه. پنهان کردن قابلیت برای عبور از اسکن می تواند Block و اقدام روی حساب را در پی داشته باشد. در مقابل، علامت زدن بی دلیل هر ابزار فنی نیز مناسب نیست. سیاست npm مثال ها را غیرجامع می داند و Trust & Safety تصمیم موردی دارد.

فیلد جدید contentPolicy در package.json

برای Package Dual-use، package.json باید فیلد contentPolicy با class برابر dual-use داشته باشد. این Metadata بخشی از Tarball است و Scanner و تیم Trust & Safety از آن استفاده می کنند. ساختار باید در Source و Artifact نهایی وجود داشته باشد؛ اگر Build فرایند package.json را بازنویسی می کند، خروجی npm pack را بررسی کنید.

نمونه زیر ساختار اعلام شده در مستندات رسمی را نشان می دهد. این فیلد توضیح کامل نیست؛ توضیح در فایل DISCLOSURE قرار می گیرد. پس از نخستین انتشار با Declaration، نسخه های بعدی نمی توانند فیلد را حذف کنند، مگر اینکه Trust & Safety وضعیت را بازبینی کند.

{
  "name": "security-toolkit",
  "version": "2.0.0",
  "contentPolicy": {
    "class": "dual-use"
  }
}

فایل DISCLOSURE چه محتوایی داشته باشد؟

DISCLOSURE باید در ریشه Tarball منتشرشده، کنار فایل هایی مانند LICENSE قرار گیرد و فقط متن باشد. فایل باید قابلیت Dual-use و کاربرد مشروع موردنظر را توضیح دهد. متن خوب روشن می کند ابزار چه عملیات حساسی انجام می دهد، چه مخاطبی دارد، در چه محیطی باید استفاده شود و چه کنترل هایی از سوءاستفاده جلوگیری می کنند.

از متن مبهم «برای اهداف آموزشی» پرهیز کنید. توضیح دهید مثلاً ابزار برای ارزیابی مجاز شبکه سازمانی طراحی شده، نیاز به Scope صریح دارد و خروجی آن چگونه Audit می شود. Secret، جزئیات مشتری یا اطلاعات Exploit فعال غیرضروری را داخل فایل قرار ندهید. npm ممکن است از این فایل در Review دستی استفاده کند.

قانون 2FA و روش های مجاز انتشار Dual-use

تمام مسیرهای انتشار Dual-use باید احراز هویت دومرحله ای را در Publish یا Promotion enforce کنند. انتشار تعاملی با 2FA مجاز است. Staged Publishing نیز مجاز است؛ Credential می تواند Package را Stage کند، اما Promotion مرحله ای است که 2FA را اعمال می کند. این مدل برای CI مناسب تر است، چون Build می تواند Artifact را آماده کند و انسان یا فرایند محافظت شده Promotion را تأیید کند.

انتشار مستقیم با Granular Token دارای bypass-2FA مجاز نیست. Trusted Publishing مبتنی بر OIDC نیز برای Publish مستقیم Dual-use مجاز نیست؛ فقط می تواند Stage کند و سپس Promotion دارای 2FA انجام شود. این تفاوت مهم است، چون بسیاری از تیم ها OIDC را کاملاً بدون تعامل طراحی کرده اند و باید Workflow را تغییر دهند.

Declaration دائمی است

وقتی یک Package با Metadata Dual-use منتشر شد، نسخه های بعدی باید contentPolicy و DISCLOSURE را حفظ کنند. حذف آن ها می تواند باعث Reject شدن Publish شود. دلیل این پایداری جلوگیری از نسخه ای است که ابتدا با Declaration اعتماد می گیرد و بعد قابلیت یا Label را پنهان می کند. حذف Declaration نیازمند Review تیم npm است.

در Monorepo، Template و Release Tool باید این فایل ها را حفظ کند. npm pack --dry-run و بررسی Tarball را به CI اضافه کنید. Test فقط Source Repository کافی نیست؛ فایل ممکن است با files، npmignore یا Build Step از Artifact حذف شود.

اگر Package Hold یا Block شد چه کنیم؟

ابتدا Release را دوباره با Version جدید تکرار نکنید. Notification، ایمیل Maintainer و وضعیت Package را بررسی کنید. اگر Appeal ارائه شده، اطلاعات دقیق، Hash Artifact، Commit، Build Provenance و توضیح قابلیت را آماده کنید. تغییر عجولانه نام فایل یا Obfuscation برای عبور از Scanner رفتار پرریسک و غیرحرفه ای است.

Runbook باید Owner، کانال تماس، تصمیم درباره اطلاع کاربران و مسیر Rollback را مشخص کند. اگر نسخه قبلی سالم است، Latest Tag را تغییر ندهید تا نسخه جدید Available و تأیید شود. در Package حیاتی، Release Window را طوری انتخاب کنید که Maintainer مسئول در دسترس باشد.

برای مصرف کنندگان Package چه تغییری دارد؟

اسکن Publish-time ریسک را کاهش می دهد اما حذف نمی کند. مصرف کننده باید Lockfile، Dependabot، Review Dependency، Cooldown و محدودیت Script را حفظ کند. GitHub هم زمان Advisoryهای OpenSSF malicious-packages را وارد GitHub Advisory Database کرده و Dependabot می تواند با فیلتر type:malware هشدار گسترده تری برای npm، PyPI و Ecosystemهای دیگر بسازد.

در Organization، Malware Alerts را از Settings، Code Security و Dependabot فعال کنید. Alert باید به Incident Process متصل باشد: شناسایی نسخه آلوده، یافتن Repositoryهای مصرف کننده، Rotate کردن Secret احتمالی، پاک سازی Cache و بررسی Build. فقط Upgrade Package کافی نیست اگر نسخه مخرب پیش تر اجرا شده باشد.

کنترل های مکمل زنجیره تأمین

Trusted Publishing، 2FA، Provenance، Branch Protection، Review Maintainer و محدودکردن Tokenها لایه های مکمل اند. Account Compromise یکی از مسیرهای اصلی انتشار مخرب است. Maintainer باید Session، Recovery Code و Member Permission را بازبینی کند. Automation Token باید Scope حداقلی و تاریخ انقضا داشته باشد.

برای Packageهای سازمانی، Owner بیش از یک نفر و فرایند Recovery تعریف کنید. Dependencyهای Build را Pin و Environment انتشار را Ephemeral کنید. خروجی npm pack را اسکن و SBOM تولید کنید. اسکن Registry جای Hygiene داخلی را نمی گیرد.

چگونه تأخیر را بدون خراب کردن UX مدیریت کنیم؟

اگر کاربران منتظر Release هستند، Status شفاف بهتر از اعلان زودهنگام است. Release Note را Draft نگه دارید و پس از Available شدن منتشر کنید. Pipeline می تواند وضعیت Published-Pending-Scan را در Dashboard نشان دهد. Timeout باید Failure قابل تشخیص بسازد و Alert برای Maintainer ارسال کند.

برای Packageهای زنجیره ای، Queue و Dependency Graph بسازید. Package B تنها زمانی Publish شود که A از Registry قابل نصب است. Test نصب باید Cache را دور بزند تا نسخه واقعی Registry بررسی شود. این جزئیات از Release نیمه کاره جلوگیری می کند.

روش های انتشار Package Dual-use

روشمجاز؟شرط
Publish تعاملیبله2FA در زمان انتشار
Granular Token با 2FAبله2FA واقعاً enforce شود
Staged Publishingبله2FA در Promotion
OIDC مستقیمخیرفقط برای Stage مجاز است
Token با bypass-2FA مستقیمخیرباید از Staging و Promotion استفاده شود

این جدول برای Packageهایی است که Dual-use اعلام شده اند. برای سایر Packageها نیز Trusted Publishing و 2FA از نظر امنیتی توصیه می شوند.

محدودیت ها، ریسک ها و نکات مهم

چک لیست آماده سازی npm publish

  1. Pipeline را برای تأخیر Availability مقاوم کنید.
  2. پس از Publish، نسخه را با Polling و Backoff از Registry بررسی کنید.
  3. Release Note و Tag عمومی را بعد از Availability نهایی کنید.
  4. برای Dual-use، contentPolicy را به package.json اضافه کنید.
  5. فایل DISCLOSURE را در ریشه Tarball قرار دهید.
  6. npm pack را در CI بررسی کنید.
  7. مسیر انتشار دارای 2FA یا Staged Promotion بسازید.
  8. Malware Alerts در Dependabot را فعال کنید.
  9. Runbook Hold، Block و Appeal داشته باشید.

تغییر را پیش از Release اضطراری آزمایش کنید. بهترین زمان اصلاح Pipeline زمانی است که نسخه حیاتی در صف انتشار نیست.

پرسش های متداول

تأخیر انتشار npm چقدر است؟

npm زمان معمول حدود پنج دقیقه را اعلام کرده، اما در زمان شلوغی یا برای پکیج بزرگ ممکن است 15 دقیقه یا بیشتر شود و تضمین SLA نیست.

contentPolicy چه مقداری دارد؟

در package.json باید contentPolicy شامل class با مقدار dual-use باشد.

فایل DISCLOSURE چیست؟

یک فایل متن آزاد در ریشه Tarball منتشرشده است که قابلیت Dual-use و کاربرد مشروع آن را توضیح می دهد.

آیا OIDC برای Dual-use ممنوع است؟

انتشار مستقیم با OIDC مجاز نیست؛ OIDC می تواند برای Stage استفاده شود و Promotion باید 2FA را enforce کند.

اگر نسخه Block شود چه می شود؟

Maintainer ممکن است Notification و مسیر Appeal دریافت کند و در موارد جدی اقدام روی حساب نیز ممکن است انجام شود.

جمع بندی سریع

  • Pipeline را از فرض «Publish مساوی Install فوری» خارج کنید.
  • برای Dual-use Metadata و DISCLOSURE را قبل از Enforcement اضافه کنید.
  • انتشار را با 2FA تعاملی یا Staged Publishing انجام دهید.
  • پس از Publish، Availability را Poll کنید و سپس Integration Test را اجرا کنید.
  • اعلان Block یا Appeal را در Runbook تیم Release قرار دهید.

امروز Pipeline انتشار npm را بازبینی کنید، مرحله انتظار Availability اضافه کنید و اگر Package شما قابلیت امنیتی Dual-use دارد، Declaration و مسیر 2FA را پیش از نسخه بعد آماده کنید.

منابع رسمی

اطلاعیه رسمی اسکن هنگام انتشار npm — رفتار اسکن، تأخیر، Block و الزامات انتشار

سیاست رسمی Dual-use در npm — ساختار contentPolicy، DISCLOSURE و روش های مجاز انتشار

گسترش هشدار بدافزار Dependabot — پوشش npm، PyPI و داده OpenSSF malicious-packages

مطالب پیشنهادی

محافظت جدید GitHub Actions؛ Workflow مشکوک چرا برای تأیید متوقف می شود؟

محافظت جدید GitHub Actions؛ Workflow مشکوک چرا برای تأیید متوقف می شود؟

GitHub Actions اکنون بعضی Workflowهای مشکوک Repository عمومی را پیش از اجرا نگه می دارد تا همکار دارای دسترسی Write آن را بررسی و تأیید کند.

GitHub Models فردا تعطیل می شود؛ راهنمای مهاجرت بدون قطعی

GitHub Models فردا تعطیل می شود؛ راهنمای مهاجرت بدون قطعی

GitHub Models در 30 ژوئیه 2026 برای همه کاربران بسته می شود. این راهنما یک برنامه عملی برای انتقال API، مدل، پرامپت، ارزیابی و کلیدها ارائه می کند.

Android 17 برای برنامه نویس ها؛ 17 تغییر مهم و چک لیست مهاجرت

Android 17 برای برنامه نویس ها؛ 17 تغییر مهم و چک لیست مهاجرت

Android 17 فقط چند API تازه اضافه نکرده است. این نسخه روی حافظه، شبکه محلی، OTP، TLS، اعلان سفارشی، WebView، MessageQueue، دستگاه های بزرگ و ارتباط میان دستگاه ها تغییراتی دار

GitHub Code Quality چیست؟ راهنمای کامل کنترل کیفیت کد قبل از Merge

GitHub Code Quality چیست؟ راهنمای کامل کنترل کیفیت کد قبل از Merge

GitHub Code Quality را از تحلیل CodeQL و هوش مصنوعی تا Coverage، Quality Gate، هزینه ها و روش فعال سازی مرحله ای در تیم، دقیق و کاربردی بشناسید.