مقدمه
در این مستند، آسیبپذیری CVE-2025-68613 بهعنوان یک نقص امنیتی بحرانی با امتیاز CVSS حدود 9.9 Critical مورد بررسی قرار میگیرد.
n8n یک پلتفرم اتوماسیون گردش کار متنباز است که برای اتصال بصری برنامهها و سرویسها برای اتوماسیون وظایف طراحی شده است. کاربران گردشهای کاری متشکل از گرهها را میسازند که هر گره نشاندهنده عملی مانند ایجاد درخواست API پردازش دادهها یا ارسال ایمیل است n8n اغلب برای خودکارسازی وظایف عملیاتی تکراری و ادغام ابزارهای امنیتی و پلتفرمهای SaaS استفاده میشود. در زیر یک نمونه گردش کار ساده آورده شده است که به ما امکان میدهد یک درخواست HTTP GET را به NVD CVE API زمانبندی کنیم خروجی را با استفاده از جاوا اسکریپت قالببندی کنیم و سپس گزارش را از طریق ایمیل و به یک کانال Slack ارسال کنیم.

پلتفرم n8n معمولاً در سه پیکربندی اصلی مستقر میشود:
• نمونههای خود-میزبان: سازمانها برای کنترل کامل و حاکمیت دادهها، n8n را در محل یا در محیطهای ابری خصوصی مستقر میکنند
• میزبانی ابری n8n.cloud: ارائه خدمات مدیریتشده با زیرساخت مشترک
• ابزارهای اتوماسیون داخلی: در شبکههای سازمانی برای خودکارسازی فرآیندهای تجاری بین سیستمهای داخلی و خارجی مستقر میشوند
نسخههای ۰.۲۱۱.۰ تا ۱.۱۲۰.۳ حاوی یک آسیبپذیری بحرانی اجرای کد از راه دور RCE در سیستم ارزیابی عبارت گردش کار هستند در صورت سوءاستفاده، این نقص به یک مهاجم احراز هویت شده امکان میدهد دستورات سطح سیستم را اجرا کند که به طور بالقوه منجر به نقض دادهها اختلال در سرویس یا به خطر افتادن کامل سیستم میشود همه اینها با امتیازاتی که به فرآیند n8n اختصاص داده شده است.
در این سند جنبههای فنی این آسیبپذیری را مورد بحث قرار خواهیم داد، نحوهی بهرهبرداری از آن را از طریق مرورگر وب نشان خواهیم داد و استراتژیهای تشخیص را بررسی خواهیم کرد.
نسخههای آسیبپذیر:
براساس مشاورههای امنیتی منتشرشده، این آسیبپذیری طیف وسیعی از نسخههای n8n را دربرمیگیرد.
تمام نسخههای n8n از 0.211.0 تا قبل ازنسخههای 1.120.4، 1.121.1 و 1.122.0 آسیبپذیر هستند.
نسخههای امن:
برای رفع کامل این آسیبپذیری، باید به یکی از نسخههای زیر ارتقا داده شود:
1.120.4 ،1.121.1،1.122.0
توصیه رسمی:
اگر روی بازه 0.221.0تا 1.120.3 هستید، به حداقل 1.120.4 یا جدیدتر ارتقا دهید.
اگر روی 1.121.0 هستید، به 1.121.1 یا بالاتر ارتقا دهید.
قدمهای آپدیت:
اگر با Docker Compose اجرا میکنید:
وارد دایرکتوری شوید که فایل docker-compose.yml در آن وجود دارد.
cd </path/to/compose>
اگر در compose نسخه پین کردید (مثلاً :1.120.3) آن را به یکی از نسخههای امن تغییر بدهید (مثلاً :1.122.0)
docker compose pull
docker compose down
docker compose up -d
docker compose logs -f --tail=200
اگر با Docker Run اجرا میکنید:
طبق داکیومنت رسمی: image جدید را pull کنید، کانتینر را stop / rm کن، دوباره اجرا کنید:
docker pull docker.n8n.io/n8nio/n8n:1.122.0
# یا آخرین Stable:
# docker pull docker.n8n.io/n8nio/n8n
docker ps -a
docker stop <container_id>
docker rm <container_id>
docker run --name=<container_name> [options] -d docker.n8n.io/n8nio/n8n:1.122.0
docker logs -f --tail=200 <container_name>
اگر با npm نصب کردید،طبق داکیومنت رسمی
npm update -g n8n
n8n -v
شرح فنی آسیبپذیری
قبل از بررسی این اکسپلویت، بیایید n8n را بررسی کنیم. این اکسپلویت بر اساس Node.js ساخته شده و از جاوا اسکریپت برای کارهای داخلی پلتفرم و منطق گردش کار کاربر استفاده میکند. معماری آن شامل موارد زیر است:
- موتور اجرای گردش کار: مؤلفه محاسباتی اصلی که مسئول هماهنگسازی اجرای گردش کار مبتنی بر گره است.
- سیستم ارزیابی عبارات: عبارات پویای پیچیده شده در دو آکولاد {{ }} را که در طول اجرای گردش کار به عنوان کد جاوا اسکریپت ارزیابی میشوند، پردازش میکند.
- گرههای کد: به کاربران اجازه میدهد کد جاوا اسکریپت یا پایتون سفارشی را به عنوان مراحل گردش کار بنویسند و قابلیتهای پلتفرم را گسترش دهند.
- 400 ادغام بومی: رابطهای از پیش ساخته شده به API ها و سرویسهای مختلف که گرهها را در گردشهای کار تشکیل میدهند
این آسیبپذیری در سیستم ارزیابی عبارات گردش کار n8n قرار دارد، جایی که عبارات ارائه شده توسط کاربران احراز هویت شده در طول پیکربندی گردش کار در یک زمینه اجرایی ناامن ارزیابی میشوند. نقص امنیتی اصلی، یک آسیبپذیری تزریق عبارات است که به مهاجمان احراز هویت شده امکان میدهد کد جاوا اسکریپت دلخواه را با امتیازات فرآیند n8n اجرا کنند. به طور خاص:
- n8n ورودی کاربر که در دو آکولاد {{ }} قرار گرفته است را به عنوان کد جاوا اسکریپت بدون محیط ایزوله یا اعتبارسنجی ورودی کافی پردازش میکند.
- ارزیاب عبارت فاقد جداسازی مناسب زمینه است و به مهاجمان اجازه میدهد از جعبه شنی ارزیابی مورد نظر فرار کنند.
- احراز هویت هیچ محافظت معناداری در برابر این آسیبپذیری ارائه نمیدهد، زیرا هر کاربر احراز هویت شدهای میتواند از آن سوءاستفاده کند
{{ (function(){ return this.process.mainModule.require('child_process').execSync('id').toString() })() }}
درون تمام این لایههای آکولاد، میتوانید (function(){ ... })()را ببینید. این الگو یک تابع ناشناس ایجاد و بلافاصله اجرا میکند. مهاجم سعی میکند ضمن حفظ زمینه اجرا، منطق پیچیدهای را کپسولهسازی کند. برای خواندن آسانتر، تابع ناشناس در زیر نشان داده شده است:function () {
return this.process.mainModule.require('child_process').execSync('id').toString()
}
بیایید نگاه دقیقتری به این اکسپلویت بیندازیم تا آن را بهتر درک کنیم. وقتی function () { ... } فراخوانی میشود، شروع به اجرای دستور return میکند. اگر با توابع آشنا نیستید، دستور return مقداری را برمیگرداند که نیاز به ارزیابی عبارتی دارد که بعد از آن میآید. در این حالت، ارزیابی با this شروع میشود.
این اکسپلویت از this.process.mainModule استفاده میکند. بیایید این را تجزیه و تحلیل کنیم:
this به شیء سراسری در زمینه اجرای Node.js اشاره دارد.
process یک شیء سراسری Node.js است که دسترسی به فرآیندهای سیستم را فراهم میکند.
mainModule به ماژول ریشه برنامه Node.js اشاره دارد
هدف این است که با دسترسی به بخشهای داخلی Node.js (ماژول ریشه) که باید برای عبارات کاربر در دسترس نباشد، محدودیتهای معمول sandbox جاوا اسکریپت را دور بزند. لازم به ذکر است که اگر sandboxing مناسب برقرار باشد، زمینه اجرای عبارات را از محیط زمان اجرای Node.js جدا میکند.
حالا که به شیء mainModule رسیدهایم .require('child_process') را میبینیم. این از require() یعنی تابع بارگذاری ماژول Node.js برای بارگذاری child_process یک ماژول اصلی Node.js برای اجرای دستورات سیستم استفاده میکند. لازم به ذکر است که عبارات کاربر هرگز نباید به سیستم ماژول Node.js به خصوص ماژولهای خطرناکی مانند child_process دسترسی داشته باشند.
تا اینجا اجرای توابع سیستمی کار سادهای است. این نمونه از payload از .execSync('id') برای اجرای دستور id روی سیستم میزبان استفاده میکند. به یاد داشته باشید که دستور id اطلاعات هویت کاربر (UID، GID، گروهها) را نمایش میدهد.
حالا که id را روی سیستم هدف اجرا کردهایم، وقت آن رسیده که خروجی را بازیابی کنیم. این payload از ..toString() برای تبدیل خروجی Buffer از execSync() به یک رشته قابل خواندن، یعنی خروجی id استفاده میکند
نقض مرز امنیتی: عبارات کاربر هرگز نباید به سیستم ماژول Node.js به ویژه ماژولهای خطرناکی مانند child_process دسترسی داشته باشند.
اکنون میتوانید ببینید که چرا اشاره کردیم که مهاجم منطق پیچیده را در تابع ناشناس کپسولهسازی میکند این شامل فراخوانیهای متوالی میشود، تا زمانی که آنها به معنای واقعی کلمه دستورات را روی سیستم آسیبپذیر اجرا کنند. به طور خلاصه، زنجیره تشدید زمینه به شرح زیر است:
- این فرآیند درون جعبه شنیِ مورد نظرِ ارزیاب عبارت شروع میشود.
- سپس از طریق این به زمینه سراسری Node.js ارتقا مییابد.
- علاوه بر این، از طریق process.mainModule.require به دسترسی سیستمی ماژول ارتقا مییابد.
- در نهایت، از طریق child_process به اجرای دستور سیستمی ارتقا مییابد.
