
Bitwarden Server v2026.9.2 - عالي - IDOR - زرع عناصر خزنة قابلة لفك التشفير في مجموعات لا يملك المستدعي صلاحية الكتابة فيها
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · bitwarden-cipher-create-acl
Bitwarden Server v2026.9.2 - Bitwarden
إنشاء عنصر تشفير للمؤسسة على مسار Entity Framework (MariaDB، Postgres، SQLite) يُسقط معرّف المستدعي قبل إرفاق المجموعة. يمكن لعضو مؤكَّد أن يزرع عنصرًا بمفتاح المؤسسة داخل مجموعة لا يملك صلاحية الكتابة فيها. يقوم أعضاء المجموعة بمزامنته كتسجيل دخول مشترك عادي.
| ID | لا يوجد CVE حتى الآن |
| CWE | CWE-863 / CWE-639 |
| CVSS | مرتفع: 7.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L |
| المنتج | Bitwarden Server |
| المتأثر | v2026.9.2 (9ee4e0eb) lite EF (MariaDB / Postgres / SQLite). MSSQL/Dapper يحتفظ بـ @UserId. |
| المصادقة | عضو مؤكَّد في المؤسسة |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1 فقط |
يقوم المهاجم بإضافة عناصر إلى خزنة مجموعة مشتركة. لا يقرأ أو يستبدل الأسرار الموجودة فيها بالفعل.
يمتلك العضو المؤكَّد في المؤسسة مفتاح المؤسسة بالفعل، لذا يُفكّ تشفير العنصر الجديد لكل من يمكنه رؤية تلك المجموعة. يعرضه Bitwarden كتسجيل دخول أو ملاحظة أو بطاقة أو مفتاح SSH مشترك عادي من داخل خزنة الشركة.
Okta، GitHub، VPN، Payroll) يشير URI الخاص به إلى مضيف يتحكم به المهاجم. يفتحه أعضاء المجموعة من Bitwarden فيهبطون على صفحة المهاجم، أو يُملأ تلقائيًا مقابل صفحة مشابهة.new AWS key، bastion SSH key، DB password after change). ينسخه أحدهم إلى الإنتاج أو إلى طرفية.Production أن يُسقط عنصرًا جديدًا فيها على lite EF.إذا لم يكن لديهم صلاحية الوصول إلى المجموعة المستهدفة، فقد يُرجع POST /api/ciphers/create رمز 404 بعد أن تكون الكتابة قد أُثبّتت بالفعل. ومع ذلك يستلم الضحايا العنصر عند المزامنة.
ثبّتُّ bitwarden/server v2026.9.2 (9ee4e0eb) بعد موجة 2026: طلب المسؤول TDE (CVE-2026-60104)، واقتطاع SSO ExternalId (CVE-2026-101878)، واستيراد المؤسسة للمجموعات الفارغة (CVE-2026-43638). تلك مغلقة. أما ACL المجموعة عند الإنشاء فلم يكن كذلك.
CiphersController.PostCreate يتحقق فقط من عضوية المؤسسة، ثم يمرّر skipPermissionCheck: true عند تعيين OrganizationId. بعد ذلك يتعامل SaveDetailsAsync مع "هذه المجموعة موجودة في المؤسسة" باعتباره الفحص الوحيد للمجموعة.
تستخدم lite MariaDB/Postgres/SQLite إطار EF. يضبط CreateAsyncReturnCipher القيمة cipher.UserId = null لوجود معرّف مؤسسة، ثم يمرّر هذا الـ null إلى UpdateCollectionsAsync. معرّف المستخدم الفارغ يعني كل المجموعات في المؤسسة. أما SQL Server Dapper فيحتفظ بـ @UserId من أجل Cipher_UpdateCollections (ReadOnly = 0). ذلك المسار هو الحالة السلبية.
المنعطفات الخاطئة المسجّلة مسبقًا: التعامل مع POST /organizations السحابي كإنشاء الاستضافة الذاتية (فهو [NotSelfHostedOnly]؛ وتحتاج lite إلى ملف ترخيص، لذا يزرع المختبر صفوف المؤسسة بعد التسجيل)؛ الزرع في مجموعة لا يستطيع المستدعي قراءتها وقراءة HTTP 404 كإخفاق (فصف CollectionCipher مُثبَّت بالفعل)؛ افتراض أن MSSQL lite سيُظهره (فـ Dapper لا يُسقط معرّف المستدعي)؛ ترك BW_ENABLE_ADMIN معطّلًا فلا تُرحّل lite أبدًا User / OrganizationDomain (فالمسؤول هو مُرحّل EF على هذه الصورة)؛ إغفال Bitwarden-Client-Version على /identity/connect/token ومشاهدة منح كلمة المرور يُرجع 400. صدفة عكسية. مسرحية.
cd lab
./run.sh
الهدف فقط http://127.0.0.1:18160. الصورة ghcr.io/bitwarden/lite:2026.9.2 بالإضافة إلى MariaDB.
SUCCESS BITWARDEN-CIPHER-CREATE-ACL create-http=404 collectioncipher=1 victim-sync-has-cipher=yes cipher=<id> negative-http=404 readonly-http=200 BITWARDEN-CIPHER-CREATE-ACL-WITNESS
زرع بلا صلاحية وصول يُرجع 404 بعد تثبيت CollectionCipher. يحتوي كل من GET /api/ciphers و /api/sync لدى الضحية على المعرّف الجديد. القراءة فقط على B تُرجع 200 وتزرع رغم ذلك. تبقى مجموعة مؤسسة أجنبية على 404 دون صف انضمام.
مرّر معرّف المستخدم الحافظ إلى UpdateCollectionsAsync في EF بالطريقة نفسها التي لا يزال CipherDetails_CreateWithCollections يمرّر بها @UserId بعد تصفير عمود UserId المخزَّن. لا تتعامل مع مستخدم فارغ على أنه "كل المجموعات" على مسار إنشاء العضو. الوجود في المؤسسة ليس صلاحية كتابة.
CiphersController.cs (Post، PostCreate)CipherService.cs (SaveDetailsAsync)CipherRepository.cs (CreateAsyncReturnCipher، UpdateCollectionsAsync)