آپدیت امنیتی Node.js ژوئیه 2026؛ چه نسخه هایی را فوراً نصب کنیم؟
Node.js در 29 ژوئیه 2026 برای شاخه های فعال 22.x، 24.x و 26.x بسته امنیتی تازه ای منتشر کرد. در این راهنما دقیقاً می بینید کدام نسخه را باید نصب کنید، هر آسیب پذیری چه سناریویی را تهدید می کند و چگونه ارتقا را در سرور، کانتینر و CI/CD با ریسک کنترل شده انجام دهید.
فهرست مطالب
- در یک نگاه
- چه اتفاقی افتاد و چه نسخه هایی امن اند؟
- سه آسیب پذیری High چه معنایی دارند؟
- ریسک های Medium و Low برای چه پروژه هایی مهم اند؟
- جدول تصمیم برای اولویت بندی
- راهنمای ارتقا بدون غافلگیری
- Docker، CI/CD و محیط های چندنسخه ای
- چگونه بعد از ارتقا صحت را تأیید کنیم؟
- اگر فعلاً امکان ارتقا نداریم چه کنیم؟
- پرسش های متداول
- جمع بندی
در یک نگاه
- شاخه های فعال متاثر: 22.x، 24.x و 26.x.
- نسخه های اصلاح شده: 22.23.2، 24.18.1 و 26.5.1.
- مهم ترین حوزه های ریسک: HTTP/2، Permission Model، HTTPS Agent، DNS، zlib، node:sqlite و Request Smuggling.
- صرف نصب پکیج های npm مشکل Runtime را حل نمی کند؛ خود باینری Node.js باید ارتقا یابد.
- نسخه های End-of-Life مسیر امنی برای Patch ندارند و باید به شاخه پشتیبانی شده مهاجرت کنند.
چه اتفاقی افتاد و چه نسخه هایی امن اند؟
پروژه Node.js انتشار امنیتی ژوئیه را پس از دو نوبت تعویق برای آزمایش و رفع مشکل زیرساختی، در 29 ژوئیه 2026 در دسترس قرار داد. این نکته مهم است چون خبر اولیه فقط زمان بندی انتشار را اعلام می کرد، اما اکنون نسخه های اصلاح شده واقعاً قابل دریافت اند. سه شاخه فعال 22.x، 24.x و 26.x به روزرسانی گرفته اند و همراه Runtime، نسخه های جدید Undici و llhttp نیز وارد بسته شده اند. بنابراین بررسی صرف package-lock.json کافی نیست؛ باید نسخه اجراشده در Production را با فرمان node --version، تصویر Docker، فایل ابزار مدیریت نسخه و Runnerهای CI کنترل کنید.
برای شاخه 22 نسخه 22.23.2، برای شاخه 24 نسخه 24.18.1 و برای شاخه 26 نسخه 26.5.1 منتشر شده است. اگر برنامه شما روی نسخه قدیمی تر همان شاخه قرار دارد، ارتقای Patch معمولاً کم ریسک ترین مسیر است، اما «Patch بودن» به معنی بی نیازی از تست نیست. رفتار HTTP، TLS، DNS و Permission Model مستقیماً با ورودی شبکه و مرز امنیتی برنامه درگیر است. سرویس هایی که Proxy، API Gateway، HTTP/2، mTLS یا اجرای کد محدودشده دارند باید تست هدفمند انجام دهند، نه اینکه فقط Health Check صفحه اصلی را سبز ببینند.
نسخه ای که در لپ تاپ توسعه دهنده دیده می شود لزوماً نسخه Production نیست. در سازمان های واقعی ممکن است چهار نسخه جدا وجود داشته باشد: نسخه داخل Dockerfile، نسخه Runner در CI، نسخه روی سرور و نسخه مورد استفاده Function یا Platform-as-a-Service. موجودی نسخه ها را قبل از Patch تهیه کنید.
سه آسیب پذیری High چه معنایی دارند؟
1) دورزدن محدودیت حافظه HTTP/2
CVE-2026-56846 به نگه داری بلوک های Header در HTTP/2 مربوط است. در شرایط آسیب پذیر، Headerهای نگه داری شده می توانند از محدودیت maxSessionMemory عبور کنند و مصرف حافظه را از راه دور بالا ببرند. اثر عملی این ضعف برای سرویسی که HTTP/2 را مستقیماً از اینترنت می پذیرد با یک برنامه داخلی ساده یکسان نیست. API عمومی، Gateway، سرویس gRPC و سامانه ای که تعداد اتصال همزمان بالایی دارد باید آن را جدی تر بگیرد. محدودکردن ترافیک یا Restart خودکار فقط پیامد را پنهان می کند؛ Patch Runtime راه حل اصلی است.
2) Heap Use-After-Free در HTTP/2
CVE-2026-56848 از فراخوانی بازگشتی عملیات ارسال هنگام پردازش دریافت در nghttp2 ناشی می شود و می تواند به Heap Use-After-Free برسد. این اصطلاح یعنی برنامه به بخشی از حافظه دسترسی پیدا می کند که عمر معتبر آن پایان یافته است. نتیجه ممکن است Crash، ناپایداری یا رفتار غیرقابل پیش بینی باشد. چون مسیر در لایه Native اتفاق می افتد، try/catch جاوااسکریپت تضمین نمی کند فرآیند نجات پیدا کند. تیم باید علاوه بر ارتقا، Crashهای Native، Exit Codeهای غیرعادی و Restartهای مکرر Pod را در بازه قبل از Patch بررسی کند.
3) بیش اعطایی دسترسی فایل در Permission Model
CVE-2026-58043 به تطبیق Prefix مسیر در ساختار Radix Tree مربوط است. برنامه ای که با --permission اجرا می شود ممکن است برای یک مسیر مجاز شود، اما به دلیل تشخیص مرز ناقص به مسیر دیگری خارج از Allowlist نیز دسترسی بگیرد. این ضعف برای همه برنامه های Node یکسان نیست؛ فقط زمانی مرز امنیتی مهم می شود که واقعاً از Permission Model برای محدودسازی کد، Plugin، ابزار Agent یا Worker استفاده کرده باشید. بااین حال، اگر روی این قابلیت به عنوان Sandbox حساب کرده اید، Patch باید فوری باشد و تست باید تلاش برای خواندن و نوشتن مسیرهای هم نام و Prefixهای نزدیک را پوشش دهد.
ریسک های Medium و Low برای چه پروژه هایی مهم اند؟
| شناسه | شدت | حوزه | اثر عملی |
|---|---|---|---|
| CVE-2026-56850 | Medium | HTTPS Agent و mTLS | احتمال استفاده مجدد هویت Client میان درخواست هایی با PFX متفاوت؛ مهم برای سرویس های چندمستاجری و اتصال به چند سامانه با گواهی های مجزا. |
| CVE-2026-58040 | Medium | TLS Session Reuse | احتمال عبور از بررسی Hostname در شرایط استفاده مجدد Session میان Policyهای هویتی متفاوت. |
| CVE-2026-58041 | Medium | node:sqlite | Iterator قدیمی SQLTagStore ممکن است پس از Reset با پارامترهای تازه دوباره نوشتن را اجرا کند؛ شاخه های 24 و 26 متاثرند. |
| CVE-2026-58042 | Medium | DNS | پاسخ دارای بیش از 256 رکورد A می تواند dns.resolveAny را به Abort فرآیند برساند. |
| CVE-2026-58045 | Medium | zlib Sync API | TypedArray دستکاری شده می تواند Assertion قابل دسترسی و Crash ایجاد کند. |
| CVE-2026-56847 | Low | Permission Model / Trace | Trace Event می تواند بیرون از مسیر مجاز فایل بنویسد. |
| CVE-2026-58039 | Low | Permission Model / Report | process.report می تواند خارج از Allowlist فایل ایجاد یا بازنویسی کند. |
| CVE-2026-58044 | Low | HTTP Client / Proxy | پنهان شدن Headerهای فراتر از محدودیت ممکن است در Proxyهای بازساز Header به Request Smuggling کمک کند. |
شدت CVE تنها معیار اولویت نیست. یک ضعف Medium در mTLS برای پلتفرمی که درخواست مشتریان مختلف را با گواهی های جدا ارسال می کند می تواند از یک ضعف High در قابلیتی که اصلاً فعال نیست مهم تر باشد. اولویت باید از ترکیب Exposure، استفاده واقعی از API، امکان کنترل ورودی مهاجم و اثر شکست ساخته شود. به همین دلیل Inventory قابلیت های Runtime به اندازه Inventory نسخه ها اهمیت دارد: آیا HTTP/2 فعال است؟ آیا node:sqlite در Production استفاده می شود؟ آیا Agent مشترک با چند PFX دارید؟ آیا Permission Model بخشی از مرز اعتماد است؟
جدول تصمیم برای اولویت بندی
| وضعیت پروژه | اولویت | اقدام پیشنهادی |
|---|---|---|
| API عمومی با HTTP/2 یا gRPC | بحرانی | Patch فوری، تست فشار اتصال و پایش حافظه و Crash. |
| Proxy یا Gateway نوشته شده با Node | بحرانی | Patch فوری و بازبینی نحوه بازسازی Header و Body. |
| سرویس دارای mTLS با چند Client Certificate | بالا | Patch و تست جداسازی Session و هویت بین مقصدها. |
| اجرای Plugin یا Agent با --permission | بالا | Patch، تست منفی مسیرها و تقویت Sandbox سیستم عامل. |
| برنامه داخلی بدون HTTP/2 و Permission Model | متوسط | Patch در چرخه اضطراری کنترل شده و Smoke Test. |
| Node.js خارج از دوره پشتیبانی | بحرانی | مهاجرت به شاخه فعال؛ انتظار Backport رسمی نداشته باشید. |
راهنمای ارتقا بدون غافلگیری
اول یک فهرست دقیق از Runtimeها بسازید. فرمان node --version را در همان محیطی اجرا کنید که برنامه واقعی اجرا می شود. برای سرویس systemd مسیر ExecStart و خروجی which node را ببینید؛ برای کانتینر، Digest تصویر و دستور docker run --rm IMAGE node --version را ثبت کنید؛ برای CI نسخه Action یا Image را کنترل کنید. سپس شاخه مقصد را تعیین کنید. اگر روی 24.x هستید، برای رفع این بسته لازم نیست همزمان به 26.x مهاجرت کنید؛ نصب 24.18.1 دامنه تغییر را محدود نگه می دارد.
node --version
npm --version
# نمونه با nvm
nvm install 24.18.1
nvm use 24.18.1
# نصب وابستگی ها از Lockfile و اجرای کنترل ها
npm ci
npm run lint
npm test
npm run buildخروجی مورد انتظار این است که Runtime نسخه اصلاح شده را گزارش کند، نصب وابستگی ها بدون تغییر ناخواسته Lockfile انجام شود و Build و Testهای موجود سبز بمانند. پس از آن، تست های هدفمند شبکه را اضافه کنید. برای HTTP/2، اتصال طولانی، Header زیاد و قطع و وصل را بسنجید. برای mTLS، هر مقصد را با Certificate صحیح و Session جدا فراخوانی کنید. برای DNS و zlib، مسیر خطا را بررسی کنید تا شکست ورودی باعث Crash کل فرآیند نشود.
نسخه Node را در فایل های قابل ردیابی Pin کنید. بسته به ابزار شما این محل می تواند .nvmrc، .node-version، engines در package.json، Dockerfile یا تنظیمات Platform باشد. فقط engines کافی نیست، چون بعضی Package Managerها آن را هشدار می دانند و Runtime را تغییر نمی دهند. هدف این است که محیط توسعه، CI و Production یک نسخه Patch مشخص یا حداقل یک Range کنترل شده داشته باشند و اختلاف نسخه در Log شروع برنامه ثبت شود.
Docker، CI/CD و محیط های چندنسخه ای
در Docker، تغییر Tag بدون Build مجدد کافی نیست. اگر Dockerfile از node:24 استفاده کند، Build قدیمی ممکن است همچنان Layer قبلی را Cache کرده باشد. تصویر را با Pull تازه بسازید، Digest پایه را ثبت کنید و سپس تصویر نهایی را Scan کنید. استفاده از Tag بسیار عمومی مانند latest ردیابی را دشوار می کند. برای Rollback نیز تصویر قبلی را نگه دارید، اما بدانید Rollback به نسخه آسیب پذیر فقط راه خروج اضطراری کوتاه مدت است و باید با کنترل شبکه و زمان بندی Patch دوباره همراه شود.
FROM node:24.18.1-bookworm-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:24.18.1-bookworm-slim
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app ./
USER node
CMD ["node", "dist/server.js"]در CI، Runnerهای Hosted و Self-hosted را جدا ببینید. Action نصب Node باید نسخه Patch را بگیرد، ولی Jobهایی که داخل Container اجرا می شوند ممکن است از Image دیگری استفاده کنند. Cache npm را می توان حفظ کرد، اما Cache باینری Runtime یا تصویر Base باید تازه شود. Pipeline خوب نسخه Node را در ابتدای Log چاپ می کند و در مرحله Deploy همان Artifact یا Image آزموده شده را جلو می برد؛ Rebuild جداگانه روی سرور می تواند نسخه دیگری وارد کند.
چگونه بعد از ارتقا صحت را تأیید کنیم؟
- نسخه Runtime را در Development، CI، Staging و هر Replica تولیدی ثبت و مقایسه کنید.
- Smoke Testهای اصلی، تست قرارداد API و تست مسیرهای حساس HTTP/2، TLS، DNS و SQLite را اجرا کنید.
- Memory، CPU، نرخ Restart، Errorهای TLS و زمان پاسخ را با Baseline پیش از ارتقا مقایسه کنید.
- یک Canary محدود منتشر کنید و پیش از Rollout کامل بازه مشاهده تعریف کنید.
- SBOM، Inventory و مستند Runbook را با نسخه جدید به روزرسانی کنید.
- Imageها و VMهای قدیمی را از Registry یا Auto Scaling Template خارج کنید تا دوباره برنگردند.
تأیید Patch تنها با دیدن شماره نسخه پایان نمی یابد. باید مطمئن شوید همه Replicaها نسخه تازه را اجرا می کنند و Load Balancer هنوز ترافیک را به نمونه قدیمی نمی فرستد. در Kubernetes، rollout status و Image ID واقعی Podها را ببینید؛ در VM Auto Scaling، Launch Template را اصلاح کنید؛ در Serverless، Runtime مدیریت شده و زمان اعمال Patch Provider را بررسی کنید. همچنین Alertهای Memory و Crash را در چند ساعت و چند روز بعد دنبال کنید، چون بعضی Regressionها فقط زیر بار واقعی دیده می شوند.
اگر فعلاً امکان ارتقا نداریم چه کنیم؟
تعویق Patch باید تصمیم مستند و زمان دار باشد، نه وضعیت نامحدود. ابتدا Exposure را کم کنید: HTTP/2 عمومی را در صورت امکان پشت Proxy به روز و کنترل شده خاتمه دهید، دسترسی سرویس را محدود کنید، نرخ و اندازه Header را در Edge کنترل کنید و مسیرهای غیرضروری را ببندید. برای Permission Model، اجرای کد ناشناس را متوقف یا به Container و حساب سیستم عامل جدا منتقل کنید. برای mTLS، Pool مشترک میان هویت های متفاوت را حذف کنید. این کنترل ها احتمال یا اثر سوءاستفاده را کم می کنند، اما جای نسخه اصلاح شده نیستند.
اگر نشانه ای از Crash غیرعادی، رشد حافظه، خطای TLS، فایل خارج از Allowlist یا درخواست های نامعمول دیده اید، موضوع را صرفاً به عنوان Patch مدیریت نکنید. Logها را حفظ کنید، Credentialهای در معرض را ارزیابی کنید، Timeline بسازید و در صورت نیاز Incident Response را فعال کنید. ارتقا آسیب پذیری را می بندد، اما آثار سوءاستفاده قبلی را پاک نمی کند.
پرسش های متداول
آیا npm update برای رفع این مشکلات کافی است؟
خیر. مشکلات اعلام شده در Runtime و وابستگی های همراه Node.js قرار دارند. باید خود نسخه Node.js به 22.23.2، 24.18.1 یا 26.5.1 ارتقا یابد. npm update می تواند وابستگی های پروژه را تغییر دهد، اما باینری Node را Patch نمی کند.
اگر فقط HTTP/1.1 استفاده کنیم باز هم باید ارتقا دهیم؟
بله. بسته فقط HTTP/2 نیست و ضعف های Permission Model، HTTPS Agent، DNS، zlib، SQLite و HTTP Client را نیز پوشش می دهد. حتی اگر هیچ کدام را مستقیم استفاده نکنید، ماندن روی نسخه آسیب پذیر ریسک نگه داری و Patch بعدی را بالا می برد.
آیا می توان از 22 مستقیم به 26 رفت؟
از نظر برنامه ریزی ممکن است، اما این تغییر یک مهاجرت Major جداست و دامنه تست بیشتری دارد. برای مهار سریع رخداد امنیتی، Patch شاخه فعلی معمولاً منطقی تر است؛ سپس مهاجرت Major را با پروژه مستقل انجام دهید.
نسخه های End-of-Life چه وضعی دارند؟
پروژه Node.js تأکید می کند نسخه های خارج از دوره پشتیبانی هنگام انتشار امنیتی باید متاثر فرض شوند. چون Patch رسمی برای آن ها تضمین نمی شود، راه اصولی مهاجرت به شاخه فعال است.
بهترین معیار موفقیت Rollout چیست؟
همه نمونه ها باید نسخه اصلاح شده را گزارش کنند، تست های هدفمند سبز باشند و نرخ خطا، Memory، Crash و Latency نسبت به Baseline بدتر نشود. علاوه بر آن، هیچ Template یا Image قدیمی نباید امکان بازگرداندن Replica آسیب پذیر را داشته باشد.
جمع بندی
انتشار 29 ژوئیه Node.js یک Patch عادی وابستگی نیست؛ چند مسیر سطح پایین شبکه، حافظه و مرز دسترسی را اصلاح می کند. نسخه مقصد را براساس شاخه فعلی انتخاب کنید، Runtime واقعی همه محیط ها را موجودی بگیرید، Patch را در Canary با تست هدفمند اجرا کنید و سپس Rollout کامل انجام دهید. اگر روی نسخه End-of-Life هستید، این رخداد را بهانه ای برای ادامه تعویق نکنید؛ مهاجرت به شاخه پشتیبانی شده بخشی از اصلاح امنیتی است.