
روابط القاعدة المشتركة لـ NocoDB قد تدعو أعضاء القاعدة الحقيقيين وتنجو من إلغاء المشاركة
روابط القاعدة المشتركة في NocoDB قد تدعو أعضاء حقيقيين للقاعدة وتعيش بعد إلغاء المشاركة
وجدت هذه المشكلة أثناء مراجعة NocoDB، مع سؤال أمني بسيط في ذهني:
هل يمكن لرابط قاعدة مشتركة عام أن يعبر الحدود من وصول مؤقت مشترك إلى عضوية قاعدة حقيقية موثقة؟
في هذه الحالة، كانت الإجابة نعم.
تم التعامل مع جلسة قاعدة مشتركة موثقة فقط بواسطة xc-shared-base-id كمشاهد عادي للقاعدة لأغراض قائمة التحكم بالوصول (ACL). نظرًا لأن أذونات المشاهد لا تزال تصل إلى نقاط نهاية إدارة الأعضاء، يمكن للمستخدم الذي لديه UUID القاعدة المشتركة فقط تعداد أعضاء القاعدة الحاليين ودعوة عنوان بريد إلكتروني عشوائي إلى القاعدة كعضو حقيقي.
يمكن لهذا المستخدم المُدعَى بعد ذلك تفعيل الدعوة من خلال عملية التسجيل العادية، والحصول على حساب موثق عادي، والاحتفاظ بالوصول إلى القاعدة حتى بعد أن يقوم المالك بتعطيل رابط القاعدة المشتركة.
أصبحت هذه المشكلة CVE-2026-46552.
المشروع: NocoDB
الإصدار المتأثر الذي تم التحقق منه: 0.301.3
أثر هذا على NocoDB، على موقعها الرسمي، تُعرض NocoDB على أنها موثوقة من قبل أكثر من 35,000 مؤسسة، مع أكثر من 20 مليون تنزيل. كما يسرد الموقع شركات مثل Accenture و Western Digital و Hyundai و Walmart و PwC و Bosch و American Express.
رابط قاعدة مشتركة عام -> xc-shared-base-id يُعالج كمشاهد عادي للقاعدة -> ACL المشاهد يصل إلى نقاط نهاية إدارة الأعضاء -> المهاجم يسرد مستخدمي القاعدة ويدعو بريدًا إلكترونيًا عشوائيًا -> المستخدم المُدعَى يُفعّل رمز التسجيل العادي -> وصول قاعدة موثق مستمر ينجو من إلغاء الرابط المشترك
NocoDB هي منصة تعاون قائمة على قواعد البيانات تعرض الوصول المستند إلى المتصفح للقواعد، والمشاركة، وإدارة البيانات الوصفية، وسير عمل عضوية المستخدمين.
وهذا يعني أن نموذج المشاركة الخاص بها هو حد أمني حقيقي.
السؤال المهم هنا لم يكن ما إذا كانت روابط القاعدة المشتركة يمكنها قراءة المحتوى المشترك.
السؤال الحقيقي كان:
هل يمكن لمبدأ المشاركة العامة تنفيذ إجراءات يجب أن تنتمي فقط لأعضاء القاعدة الموثقين؟
في هذه الحالة، كان ذلك ممكنًا.
ميزات المشاركة العامة سهلة التقليل من شأنها.
هذا خطأ.
بمجرد أن يدعم التطبيق:
الخطر الرئيسي ليس مجرد كشف البيانات.
الخطر الأقوى هو انهيار الحدود:
كانت هذه هي المشكلة الحقيقية هنا.
لم يكن هذا خطأ في التحقق من تسجيل الدخول. لم يكن مشكلة تزوير رمز مميز. لم يكن عيبًا في إعادة تعيين كلمة المرور.
كان فشلًا كلاسيكيًا في حدود الصلاحية:
لم أتعامل مع هذا الأمر عن طريق استكشاف نقاط النهاية بشكل عشوائي وأمل أن يستجيب شيء مثير للاهتمام.
المسار الأقوى هو تحديد أعلى حد ثقة ذي قيمة أولاً.
بالنسبة لـ NocoDB، كان ذلك الحدود بين:
لا ينبغي أن تكون هاتان الحالتان قابلتين للتبادل.
من المفترض أن يمثل رابط القاعدة المشتركة وصولًا محددًا وقابلًا للإلغاء وقائمًا على الرابط. لا ينبغي أن يكون قادرًا على إنشاء مبادئ جديدة طويلة العمر داخل القاعدة.
هذا هو بالضبط الحدود التي فشلت هنا.
جاءت الثغرة الأمنية من كيفية دمج الوصول إلى القاعدة المشتركة في مسار ACL العادي.
في تدفق الواجهة الأمامية للقاعدة المشتركة، تم حقن xc-shared-base-id بينما تمت إزالة رؤوس المصادقة العادية.
ثم، في الواجهة الخلفية، قبلت BaseViewStrategy xc-shared-base-id وترجمت الرابط المشترك مباشرة إلى roles / base_roles عادية مشتقة من تكوين القاعدة المشتركة.
كانت تلك هي المشكلة الأولى.
المشكلة الثانية كانت أن أذونات مستوى المشاهد لا تزال تتضمن إجراءات إدارة الأعضاء.
في طبقة ACL، يمكن لـ ProjectRoles.VIEWER الوصول إلى:
baseUserListuserInviteحرست هذه الأذونات مسارات التعريف العادية:
GET /api/v2/meta/bases/:baseId/usersPOST /api/v2/meta/bases/:baseId/usersلذلك سُمح لجلسة المشاركة العامة بضرب نقاط نهاية العضوية المخصصة للمشاركين الحقيقيين في القاعدة.
الخطوة الأخيرة كانت في عملية الدعوة نفسها.
قامت BaseUsersService.userInvite() بفحص قوة الدور، ثم أنشأت:
invite_tokenوبالنسبة لجلسات القاعدة المشتركة:
invited_by nullلأنه لم تكن هناك هوية مُدعٍ موثقة حقيقية وراء الطلب.
هذه هي سلسلة الخطأ بأكملها.
لأن امتلاك رابط القاعدة المشتركة كان كافيًا.
لم يحتج المهاجم إلى:
xc-authكانت سلسلة الاستغلال مباشرة:
هذا يحول مشاركة الرابط القابلة للإلغاء إلى عضوية دائمة.
الفرق المهم هو الاستمرارية عبر الإلغاء.
لم يكن هذا مجرد:
"يمكن للمشاهد استدعاء نقطة نهاية المشاهد"
لم يكن المبدأ الضعيف مشاهدًا عاديًا موثقًا.
لقد كان جلسة مشاركة عامة.
هذا مهم لأن التطبيق تعامل مع مبدأ عابر ومحدود بالرابط كما لو كان موثوقًا بما يكفي لـ:
لم يكن السؤال الحقيقي:
"هل يمكن للمستخدم المشترك قراءة البيانات المشتركة؟"
كان السؤال الحقيقي:
"هل يمكن تحويل وصول المشاركة العامة إلى وصول موثق دائم ينجو من إلغاء المشاركة؟"
كانت الإجابة نعم.
لهذا السبب هذه ثغرة صلاحية حقيقية وليست مجرد سلوك تطبيق مفاجئ.
لقد تحققت من ذلك محليًا ضد:
0.301.3dac49b0122c5ee655fb8f46a1b6e42dfeec1f3adhttp://127.0.0.1:8080كان إعادة الإنتاج مباشرًا.
أولاً، قمت بتسجيل الدخول كحساب مالك عادي، وأنشأت قاعدة جديدة، وأنشأت جدولًا، وفعّلت الوصول إلى القاعدة المشتركة كـ viewer:
PATCH /api/v2/meta/bases/<baseId>/shared
Content-Type: application/json
{
"roles": "viewer"
}
أعاد ذلك UUID القاعدة المشتركة.
ثم، بدون إرسال أي xc-auth، استخدمت فقط:
xc-shared-base-id: <sharedBaseUuid>
باستخدام هذا الرأس فقط، قمت باستدعاء:
GET /api/v2/meta/bases/<baseId>/users
أعاد ذلك 200 OK وكشف عن أعضاء حقيقيين في القاعدة، بما في ذلك عناوين البريد الإلكتروني.
باستخدام xc-shared-base-id فقط أيضًا، قمت باستدعاء:
POST /api/v2/meta/bases/<baseId>/users
Content-Type: application/json
{
"email": "[email protected]",
"roles": "viewer"
}
أعاد ذلك أيضًا 200 OK.
بالنسبة للتحقق المخبري المحلي بدون تسليم البريد الإلكتروني، أكدت مباشرة في قاعدة بيانات التعريفات SQLite أن:
nc_users_v2 احتوت على المستخدم المُدعَى مع invite_token غير فارغnc_base_users_v2 احتوت على صف عضوية حقيقي للقاعدة المستهدفةinvited_by NULLثم قمت بتفعيل الدعوة من خلال عملية التسجيل العادية:
POST /api/v2/auth/user/signup
Content-Type: application/json
{
"email": "[email protected]",
"password": "Password123.",
"token": "<invite_token>"
}
باستخدام xc-auth التي تم إرجاعها، قمت باستدعاء:
GET /api/v2/meta/bases/<baseId>/tables
أعاد ذلك 200 OK.
أخيرًا، كمالك، قمت بتعطيل رابط القاعدة المشتركة:
DELETE /api/v2/meta/bases/<baseId>/shared
بعد ذلك:
xc-shared-base-id مع 401xc-auth العادي مع 200200200200200200401200هذا أثبت الادعاء الأمني المركزي:
دعوة قاعدة مشتركة ناجحة واحدة كانت كافية لإظهار فشل الصلاحية.
لكن سلسلة التحقق الكاملة كانت مهمة لسببين.
أظهرت أن هذا لم يكن مجرد كشف لنقطة نهاية.
جلسة المشاركة العامة لم تصل فقط إلى واجهة برمجة تطبيقات مقيدة. لقد أكملت سلسلة تحويل الامتياز الكاملة:
أثبتت أن هذا لم يكن مُلغيًا ذاتيًا.
التأثير الأكثر خطورة جاء بعد تعطيل الرابط المشترك:
هذا هو ما حوّل وصول الرابط المؤقت إلى استمرارية وصول دائمة.
تسمح هذه الثغرة لأي شخص لديه رابط قاعدة مشتركة بـ:
التأثير الرئيسي هو السرية، لأن المهاجم يمكنه الحفاظ على وصول قراءة دائم لبيانات القاعدة المشتركة من خلال حساب موثق عادي.
هناك أيضًا تأثير على السلامة، لأن مبدأ المشاركة العامة يمكنه تعديل حالة التحكم بالوصول عن طريق إضافة أعضاء جدد إلى القاعدة.
هذه نتيجة أقوى من تسرب البيانات العادي. إنه كسر لحدود الامتياز بين المشاركة المجهولة والعضوية الموثقة.
يُصنف هذا الأمر بشكل معقول على أنه عيب في الصلاحية عبر النطاق مع تأثير على السرية.
CVSS:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N
هذا المتجه يناسب السلوك الأساسي هنا:
اتجاه الإصلاح واضح.
يجب ألا ترث جلسات القاعدة المشتركة قدرات إدارة الأعضاء.
على الأقل:
baseUserList و userInvite من أي أذونات يمكن الوصول إليها عبر xc-shared-base-idGET و POST /api/v2/meta/bases/:baseId/usersتم التحقق من هذه المشكلة محليًا ضد NocoDB 0.301.3 على الالتزام dac49b0122c5ee655fb8f46a1b6e42dfeec1f3ad.
أظهر التقرير:
xc-shared-base-id إلى أدوار القاعدة العاديةتم تعيين المشكلة:
CVE-2026-46552
الدرس الرئيسي بسيط:
الوصول عبر الرابط المشترك ليس هو نفس الشيء مثل العضوية الموثوقة.
الكثير من الأنظمة تقع في مشاكل عندما تدمج هاتين الفكرتين في نفس نموذج الدور.
قد يبدو الرابط المشترك مشابهًا من الناحية التشغيلية لحساب مشاهد، لكن افتراضات الثقة مختلفة:
إذا كان بإمكان هذا المبدأ الأقل ثقة تنفيذ إجراءات إدارية أو إنشاء هويات دائمة جديدة، فإن حدود المشاركة مكسورة بالفعل.
هذا هو الاستنتاج الحقيقي.
لم تكن هذه الثغرة حول تجاوز المصادقة بالكامل.
كانت حول دمج مستويين من الثقة كان يجب أن يظلوا منفصلين.
في NocoDB، كان من المفترض أن يوفر رابط القاعدة المشتركة وصولًا مؤقتًا وقابلًا للإلغاء إلى المحتوى المشترك. بدلاً من ذلك، يمكن استخدامه لتعداد الأعضاء، ودعوة مستخدم حقيقي إلى القاعدة، وتحويل وصول المشاركة العامة إلى عضوية موثقة دائمة تنجو من إلغاء المشاركة.
لهذا السبب أصبحت CVE-2026-46552.