Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
أدوات/GitHubGitHub/kai-one001/react-router-cve-2025-61686-
التحليل الثابتتحليل الثغرات الأمنيةتحليل الكودالاستغلالأمن الويبالتعلم والتعليم
GitHubkai-one001/react-router-cve-2025-61686-

React-Router-CVE-2025-61686-

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

الأكثر شعبية

عرض الكل →

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

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

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

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

تقرير تحليل الثغرة الأمنية CVE-2025-61686

نظرة عامة على الثغرة

CVE ID: CVE-2025-61686
الإصدارات المتأثرة: @react-router/node 7.0.0 إلى 7.9.3
نوع الثغرة: اجتياز المسار (Path Traversal) / عبور الدليل

آلية الثغرة

1. موقع الثغرة

توجد الثغرة في الدالة getFile() والمنطق المرتبط بعمليات الملفات داخل ملف packages/react-router-node/sessions/fileStorage.ts.

2. تحليل المشكلة الأساسية

2.1 مصدر Session ID

في السطر 267 من ملف packages/react-router/lib/server-runtime/sessions.ts:

root@kitploit:~
async getSession(cookieHeader, options) {
  let id = cookieHeader && (await cookie.parse(cookieHeader, options));
  let data = id && (await readData(id));
  return createSession(data || {}, id || "");
}

يتم استخراج Session ID من الكوكيز من خلال طريقة cookie.parse().

2.2 منطق تحليل الكوكيز

في الدالة decodeCookieValue() ضمن ملف packages/react-router/lib/server-runtime/cookies.ts:

root@kitploit:~
async function decodeCookieValue(
  value: string,
  secrets: string[],
): Promise<any> {
  if (secrets.length > 0) {
    // 如果配置了 secrets,会验证签名
    for (let secret of secrets) {
      let unsignedValue = await unsign(value, secret);
      if (unsignedValue !== false) {
        return decodeData(unsignedValue);
      }
    }
    return null;  // 签名验证失败返回 null
  }
  
  // 如果没有配置 secrets(未签名),直接返回解码后的值
  return decodeData(value);
}

المشكلة الأساسية: عندما تكون الكوكيز غير موقّعة (secrets مصفوفة فارغة أو غير مضبوطة)، تقوم decodeCookieValue بإرجاع قيمة الكوكيز بعد فك الترميز مباشرة، مما يتيح للمهاجم التحكم الكامل في هذه القيمة.

2.3 منطق بناء المسار

في ملف packages/react-router-node/sessions/fileStorage.ts:

root@kitploit:~
export function getFile(dir: string, id: string): string {
  // Divide the session id up into a directory (first 2 bytes) and filename
  // (remaining 6 bytes) to reduce the chance of having very large directories,
  return path.join(dir, id.slice(0, 4), id.slice(4));
}

تقوم هذه الدالة بتقسيم Session ID إلى جزأين:

  • أول 4 أحرف كاسم الدليل: id.slice(0, 4)
  • الأحرف المتبقية كاسم الملف: id.slice(4)

ثم يتم ربط المسار باستخدام path.join().

2.4 طريقة استغلال الثغرة

سيناريو الهجوم: عند استخدام createFileSessionStorage() وكانت الكوكيز غير موقّعة:

  1. يمكن للمهاجم إنشاء Session ID خبيث، على سبيل المثال: ../../etc/passwd

  2. معالجة الدالة getFile():

    • id.slice(0, 4) = ../.
    • id.slice(4) = /etc/passwd
    • path.join(dir, ../., /etc/passwd)
    • على الرغم من أن path.join() تعمل على تطبيع المسار، إلا أنه إذا كان dir مسارًا نسبيًا بالفعل أو بعد المعالجة، فقد يظل اجتياز المسار ممكنًا

طريقة استغلال أكثر دقة:

  • Session ID: ....//etc/passwd
    • id.slice(0, 4) = ....
    • id.slice(4) = //etc/passwd
    • إذا لم تتم المعالجة بشكل صحيح، فقد يؤدي ذلك إلى الوصول إلى /etc/passwd

أو:

  • Session ID: ../../../etc/passwd(16 حرفًا)
    • id.slice(0, 4) = ../.
    • id.slice(4) = ./etc/passwd
    • قد يؤدي دمج ذلك مع سلوك path.join() إلى اجتياز المسار

3. العمليات المتأثرة

جميع عمليات الملفات التالية قد تتأثر:

  1. readData(id) - عند قراءة بيانات الجلسة

    root@kitploit:~
    async readData(id) {
      try {
        let file = getFile(dir, id);
        let content = JSON.parse(await fsp.readFile(file, "utf-8"));
        // ...
      }
    }
    
  2. updateData(id, data, expires) - عند تحديث بيانات الجلسة

    root@kitploit:~
    async updateData(id, data, expires) {
      let content = JSON.stringify({ data, expires });
      let file = getFile(dir, id);
      await fsp.mkdir(path.dirname(file), { recursive: true });
      await fsp.writeFile(file, content, "utf-8");
    }
    
  3. deleteData(id) - عند حذف بيانات الجلسة

    root@kitploit:~
    async deleteData(id) {
      try {
        await fsp.unlink(getFile(dir, id));
      }
    }
    

4. تأثير الهجوم

  1. قراءة الملفات: قد يتمكن المهاجم من قراءة أي ملف على الخادم (اعتمادًا على صلاحيات عملية خادم الويب)
  2. كتابة الملفات: قد يتمكن المهاجم من كتابة ملفات على الخادم، مما قد يؤدي إلى:
    • تسريب البيانات
    • حقن الكود
    • تصعيد الصلاحيات
  3. حذف الملفات: قد يتمكن المهاجم من حذف ملفات على الخادم

5. شروط تفعيل الثغرة

يجب استيفاء جميع الشروط التالية في الوقت نفسه:

  1. استخدام طريقة createFileSessionStorage()
  2. الكوكيز غير موقّعة (لم يتم ضبط secrets في إعدادات cookie أو أن secrets مصفوفة فارغة)
  3. تمتلك عملية خادم الويب صلاحيات قراءة وكتابة على الملفات المستهدفة

نتائج مراجعة الكود

مسار الكود الحرج

root@kitploit:~
getSession(cookieHeader) 
  → cookie.parse(cookieHeader) 
    → decodeCookieValue(value, secrets)  // 未签名时直接返回 value
      → readData(id) 
        → getFile(dir, id)  // 路径拼接,存在路径遍历风险
          → fsp.readFile(file) / fsp.writeFile(file) / fsp.unlink(file)

جذر المشكلة

  1. غياب التحقق من المدخلات: الدالة getFile() لا تتحقق من الوسيط id ولا تقوم بتطبيعه
  2. الاعتماد على تطبيع path.join(): على الرغم من أن path.join() تطبّع المسار، إلا أنه في حالات معينة (مثل احتواء المسار على .. قبل الربط) قد يظل اجتياز المسار ممكنًا
  3. الكوكيز غير الموقّعة: تسمح للمهاجم بالتحكم الكامل في قيمة Session ID
تنزيل الأداة