Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-34213 — يمكن لمستخدم Docmost ذو صلاحية منخفضة تقديم attachmentId ضحية إلى نقطة نهاية التحميل العامة واستبدال المرفق المخزن لصفحة أخرى داخل نفس مساحة العمل. | Kitploit
أدوات/GitHubGitHub/0xmrma/cve-2026-34213
تحليل الثغرات الأمنيةاستغلال تطبيقات الويباختبار الاختراقالأوراق والأبحاثالتعلم والتعليم
GitHub0xmrma/cve-2026-34213

CVE-2026-34213

يمكن لمستخدم Docmost ذو صلاحية منخفضة تقديم attachmentId ضحية إلى نقطة نهاية التحميل العامة واستبدال المرفق المخزن لصفحة أخرى داخل نفس مساحة العمل.

عرض المستودع
53منذ 3 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2026-34213

يمكن لمستخدم Docmost ذي صلاحيات منخفضة توفير attachmentId خاص بالضحية إلى نقطة نهاية التحميل العامة والكتابة فوق مرفق مخزّن في صفحة أخرى داخل نفس مساحة العمل.

مقدمة

لقد حددت وكشفت بشكل مسؤول وأعدت إنتاج ثغرة في التفويض عالية الخطورة في Docmost، منصة التوثيق التعاوني مفتوحة المصدر.

يقدم الموقع الرسمي لـ Docmost نفسه كويكي محلي جاهز للمؤسسات مع أكثر من 3 ملايين تحميل، ويذكر أنه موثوق من قبل فرق في مؤسسات تشمل مدينة فيلنيوس، Bechtle، الحكومة الأسترالية، الصليب الأحمر، وETS Quebec.

كان الخلل موجودًا في مسار تحميل الملفات العام الذي يستخدمه Docmost أيضًا لتدفقات حفظ/تحديث المخططات.

كنت أراجع ذلك الكود مع سؤال محدد جدًا في ذهني:

ماذا يحدث إذا أثبتت نقطة نهاية التحميل صلاحية التحرير في صفحة واحدة، ولكن الهدف المراد الكتابة فوقه يتم تحديده باستخدام معرف مرفق منفصل يتحكم به المستخدم؟

في هذه الحالة، أدى هذا السؤال مباشرة إلى فشل حقيقي في ربط الكائنات.

سمح Docmost للمتصل بإرسال:

  • pageId لصفحة يُسمح له بتحريرها، و
  • attachmentId ينتمي إلى صفحة مختلفة في نفس مساحة العمل

قام الخادم بالفعل بإجراء فحص تناسق للكتابة فوق، لكن الحارس استخدم منطقًا منطقيًا خاطئًا.

هذا يعني أن الطلب يمكن أن يمر عبر التفويض ويكتب فوق مرفق الضحية على أي حال.

أصبحت هذه المشكلة CVE-2026-34213.

Docmost: docmost/docmost
الاستشارة: GHSA-89fp-2hch-j9gp
CVE: CVE-2026-34213
تم التصحيح في: v0.71.0

photo0 ---

سلسلة الهجوم

pageId يتحكم به المهاجم مع صلاحية تحرير -> attachmentId ضحية يتحكم به المهاجم -> حارس كتابة فوق معيب يعالج الكتابة فوق عبر الصفحات على أنها صالحة -> إعادة بناء مسار التخزين من attachmentId الضحية -> بايتات المهاجم تحل محل ملف الضحية -> تستمر صفحة الضحية في خدمة المرفق المعدل


ماذا يفعل هذا الجزء من Docmost

يقوم Docmost بتخزين المرفقات المرفوعة للصفحات كسجلات قاعدة بيانات بالإضافة إلى ملفات داعمة في التخزين.

بالنسبة للتحميلات العادية، يقوم الخادم بإنشاء معرف مرفق جديد وكتابة ملف جديد.

بالنسبة لتدفقات حفظ/تحديث المخططات، يعيد العميل استخدام attachmentId موجود عن قصد بحيث يمكن تحديث نفس ملف المخطط في مكانه بدلاً من إنشاء سجل مرفق جديد في كل مرة.

هذا السلوك مشروع في حد ذاته.

المشكلة هي أنه يُنشئ مسارًا عالي المخاطرة:

  • إدخال واحد يحدد الصفحة التي يتم تفويضها
  • إدخال آخر يحدد المرفق الذي يتم الكتابة فوقه

عندما تخلط نقطة نهاية بين هاتين المسؤوليتين، يجب على التنفيذ ربطهما معًا بالضبط.

لم يفعل Docmost ذلك.


لماذا كان هذا السطح يستحق النظر

نقاط النهاية المختلطة للإنشاء/التحديث هي أماكن شائعة لأخطاء التفويض.

السبب بسيط:

  • تدفقات الإنشاء عادةً ما تُفوض ضد الكائن الحاوي
  • تدفقات التحديث عادةً ما تُفوض ضد السجل الموجود
  • إذا حاولت نقطة نهاية واحدة القيام بكليهما، فمن السهل التحقق من الشيء الخطأ أولاً ثم معالجة المعرف الثاني على أنه "مجرد بيانات وصفية"

هذا هو النمط بالضبط هنا.

قام POST /api/files/upload بالتحقق من أن المتصل يمكنه تحرير الصفحة المسماة بـ pageId.

ولكن إذا تم توفير attachmentId أيضًا، تحول الخادم إلى مسار الكتابة فوق وحدد سجل مرفق موجود بشكل منفصل.

هذا جعل السؤال الأمني الحرج هو:

هل يُثبت مسار الكتابة فوق أن المرفق المحدد ينتمي بالفعل إلى الصفحة المفوّضة؟

كانت الإجابة في الإصدارات الضعيفة: لا.


السبب الجذري

كان السبب الجذري تجاوز التفويض من خلال مفتاح يتحكم به المستخدم، بالإضافة إلى خطأ في المنطق المنطقي في حارس الكتابة فوق.

بدا التدفق الضعيف كالتالي:

  1. AttachmentController.uploadFile() قرأ pageId من بيانات النموذج متعدد الأجزاء.
  2. قام بتحميل تلك الصفحة واستدعى validateCanEdit(page, user).
  3. قبل بشكل منفصل attachmentId اختياريًا من نفس الطلب.
  4. AttachmentService.uploadFile() قام بتحميل المرفق الموجود عبر ذلك المعرف الذي قدمه المهاجم.
  5. حاول حارس الكتابة فوق التحقق من أن المرفق الموجود يطابق الصفحة المفوّضة.
  6. استخدم الحارس && بدلاً من الرفض عند أي عدم تطابق.

كان الحارس الضعيف:

if (
  existingAttachment.pageId !== pageId &&
  existingAttachment.fileExt !== preparedFile.fileExtension &&
  existingAttachment.workspaceId !== workspaceId
) {
  throw new BadRequestException("File attachment does not match");
}

هذا الشرط يرفض الطلب فقط إذا:

  • معرف الصفحة غير متطابق، و
  • امتداد الملف غير متطابق، و
  • معرف مساحة العمل غير متطابق

كل ذلك في نفس الوقت.

هذا هو عكس ما يجب أن يفعله حارس الكتابة فوق.

بالنسبة لحالة الهجوم الحقيقية، بقي المهاجم عن قصد داخل نفس مساحة العمل.

لذا:

  • existingAttachment.workspaceId !== workspaceId كانت false

بمجرد أن يصبح هذا المعامل false، تم تقييم شرط && بالكامل إلى false، حتى لو كان المرفق ينتمي إلى صفحة مختلفة.

لذا تعامل الخادم مع الكتابة فوق عبر الصفحات على أنها صالحة.

كان هذا هو النصف الأول من الخلل.

النصف الثاني هو ما جعل التأثير حقيقيًا.

بعد الفحص، أعادت الخدمة بناء مسار التخزين الوجهة باستخدام attachmentId واسم الملف اللذين قدمهما المهاجم:

const filePath =
  `${getAttachmentFolderPath(AttachmentType.File, workspaceId)}/` +
  `${attachmentId}/${preparedFile.fileName}`;

ثم، في مسار التحديث، قام Docmost فقط بتحديث البيانات الوصفية القابلة للتغيير مثل:

  • fileSize
  • updatedAt

لم يقم بإعادة ربط الملكية بصفحة المهاجم.

لذا استمرت صفحة الضحية في الإشارة إلى نفس سجل المرفق ونفس معرف المرفق. فقط بايتات الملف الأساسية تغيرت.

لهذا لم يكن هذا مجرد عدم تطابق غير ضار.

كانت بدائية كتابة فوق غير مصرح بها ودائمة.


لماذا هذه مشكلة أمنية، وليست مجرد خطأ منطقي

لم يكن هذا خطأ تجميليًا ولم يكن مشكلة تضارب في اسم الملف.

لم يحتاج المهاجم إلى سباق. لم يحتاج المهاجم إلى تخمين مسار عشوائي. لم يحتاج المهاجم إلى صلاحية كتابة على صفحة الضحية.

كل ما احتاجه هو:

  • صلاحية قراءة لمعرفة مرجع مرفق ضحية، و
  • صلاحية كتابة على أي صفحة أخرى في نفس مساحة العمل

من هناك، يمكنه استبدال بايتات الملف المخزنة لمرفق صفحة أخرى بينما تستمر صفحة الضحية في الإشارة إلى ذلك المرفق وخدمته كما لو لم يتغير شيء.

هذا فشل مباشر في التكامل.

من الناحية العملية، يمكن للمهاجم:

  • التلاعب بالمخططات
  • استبدال المرفقات بمحتوى مضلل
  • إتلاف الملفات المشار إليها
  • إنشاء مسارات تدقيق مربكة لأن المرفق لا يزال يبدو أنه ينتمي إلى صفحة الضحية

النقطة المهمة هي هذه:

قبل الخادم هدفًا للكتابة فوق اختاره المهاجم، دون ربطه بالصفحة التي تم التحقق من صلاحية تحريرها بالفعل.

هذا فشل في التحكم بالوصول، وليس مجرد سوء النظافة المنطقية.


لماذا كان الاستغلال عمليًا

كان الاستغلال عمليًا بشكل خاص لمرفقات المخططات.

يعيد عميل Docmost استخدام attachmentId عن قصد لحفظ المخططات ويستخدم أسماء ملفات حتمية:

  • diagram.excalidraw.svg
  • diagram.drawio.svg

هذا مهم لأنه يقلل من متطلبات المهاجم.

بالنسبة للمرفقات العامة، يحتاج المهاجم إلى كليهما:

  • معرف مرفق الضحية
  • اسم ملف الضحية

بالنسبة للمخططات، اسم الملف متوقع بالفعل.

لذا إذا كان بإمكان المهاجم قراءة محتوى صفحة الضحية، فغالبًا ما يمكنه استرداد القطعة المفقودة الوحيدة التي يحتاجها:

  • attachmentId الضحية

في إعداد التحقق الخاص بي، استخدمت هذا المسار بالضبط:

  • كان لدى المهاجم صلاحية قارئ فقط لمساحة الضحية
  • كان لدى المهاجم صلاحية كاتب لمساحة مختلفة يتحكم بها المهاجم
  • تنتمي كلتا المساحتين إلى نفس مساحة العمل

كان ذلك كافياً.

عبر الاستغلال حدود الصفحات وحدود المساحات داخل نفس مساحة العمل، مع استمرار تلبية فحص مساحة العمل المعيب.


إثبات المفهوم

لقد تحققت من المشكلة مباشرة ضد Docmost v0.70.3 باستخدام مختبر قابل للتصميم مبني من docmost/docmost:0.70.3 و Postgres و Redis.

كان تدفق PoC كالتالي:

  1. إنشاء حساب مالك.
  2. إنشاء مساحة ضحية ومساحة يتحكم بها المهاجم في نفس مساحة العمل.
  3. دعوة مستخدم ثانٍ كمهاجم.
  4. منح المهاجم:
    • صلاحية قارئ لمساحة الضحية
    • صلاحية كاتب لمساحة المهاجم
  5. في مساحة الضحية، تحميل مرفق مخطط إلى صفحة ضحية.
  6. كمهاجم، استرداد معلومات صفحة الضحية وملاحظة attachmentId الضحية.
  7. إرسال POST /api/files/upload مع:
    • pageId = معرف صفحة المهاجم
    • attachmentId = معرف مرفق الضحية
    • file = ملف بديل يتحكم به المهاجم باستخدام اسم ملف الضحية
  8. تنزيل مرفق الضحية قبل وبعد الكتابة فوق ومقارنة التجزئة.

كان شكل الطلب الأدنى:

POST /api/files/upload
Content-Type: multipart/form-data
تنزيل الأداة