
مدونة حول CVE-2026-59827، إلغاء تسلسل غير آمن لمخرجات استعلام H2
GHSA-w95f-x9v9-wv36 | CVSS 9.9 حرج | CWE-502: إلغاء تسلسل بيانات غير موثوقة
CVE-2026-59827 هي ثغرة أمنية حرجة لتنفيذ التعليمات البرمجية عن بُعد في Metabase، منصة الذكاء التجاري وتحليل البيانات مفتوحة المصدر الشهيرة. يكمن الخلل في كيفية معالجة Metabase لنتائج الاستعلامات التي يعيدها اتصال قاعدة بيانات H2. عندما يُعيد استعلام SQL أصلي ضد مصدر H2 عمودًا مكتوبًا على أنه OTHER، يقوم Metabase بإلغاء تسلسل البايتات الخام لذلك العمود إلى كائن Java دون إجراء أي تحقق. لذلك، يمكن لمستخدم موثَّق يمكنه تشغيل استعلامات أصلية أن يُهرِّب حمولة متسلسلة ضارة إلى مجموعة النتائج ويُؤدي إلى تنفيذ تعليمات برمجية عشوائية على الخادم الذي يستضيف Metabase.
تم تخصيص درجة CVSS تبلغ 9.9 للثغرة، مما يعكس الشروط المسبقة البسيطة المطلوبة وتنفيذ التعليمات البرمجية الكامل على جانب الخادم الناتج عن الاستغلال الناجح.
تُصدر Metabase مسارين إصدارين متوازيين من نفس دورة الإصدار. تستخدم النسخة مفتوحة المصدر أرقام إصدارات مسبوقة بالرقم 0 — على سبيل المثال، v0.61.1. تستخدم النسخة المؤسسية (التجارية) أرقام إصدارات مسبوقة بالرقم 1 — على سبيل المثال، v1.61.1. تشترك كلا النسختين في نفس قاعدة التعليمات البرمجية الأساسية ويتم إصدارهما معًا، لذا فإن الثغرة التي تؤثر على v1.61.0 تؤثر أيضًا على v0.61.0. في جميع أنحاء هذا التقرير، تُكتب أرقام الإصدارات باستخدام البادئة 1.xx للمؤسسية، ولكن كل إصدار متأثر يُرتبط مباشرة بنظيره مفتوح المصدر 0.xx عن طريق استبدال 1 البادئة بـ 0.
تم الكشف عن كل من CVE-2026-59826 و CVE-2026-59827 معًا في يوليو 2026. يتشاركان نطاقات إصدارات متداخلة لكن لهما نقاط تصحيح مختلفة.
الإصدارات المؤسسية الثغرة هي 1.58.0 حتى 1.58.14، و 1.59.0 حتى 1.59.11، و 1.60.0 حتى 1.60.6.2، و 1.61.0 حتى 1.61.1.3. الإصدارات مفتوحة المصدر المقابلة هي 0.58.0 حتى 0.58.14، و 0.59.0 حتى 0.59.11، و 0.60.0 حتى 0.60.6.2، و 0.61.0 حتى 0.61.1.3.
تم إصدار تصحيح داخلي لأول مرة كـ 1.61.1.4 (مؤسسية) و 0.61.1.4 (مفتوحة المصدر). أول إصدار مُصحَّح متاح للجمهور في سلسلة 1.61 هو 1.61.2 (v1.61.2.x / v0.61.2.x). تم تصحيح مثيلات Metabase Cloud تلقائيًا بواسطة المزود.
الإصدارات المؤسسية الثغرة هي 1.55.0 حتى 1.58.15.0، و 1.59.0 حتى 1.59.11، و 1.60.0 حتى 1.60.6.2، و 1.61.0 حتى خط 1.61.1.x بأكمله. أول إصدار عام مُصحَّح بالكامل هو 1.61.2 (v1.61.2.x / v0.61.2.x). نطاق CVE-2026-59826 أوسع، حيث يعود إلى خط إصدار 1.55، مما يعكس وجود مسار التعليمات البرمجية لإنشاء قاعدة البيانات غير المُتحقق منه بشكل كافٍ لفترة أطول.
تسمح آلية التسلسل في Java بتحويل كائن في الذاكرة إلى تيار مسطح من البايتات، وتخزينه أو نقله، ثم إعادة بنائه لاحقًا عن طريق استدعاء ObjectInputStream.readObject(). الخاصية الحرجة لهذه الآلية هي أن إعادة البناء تنفذ تعليمات برمجية. يتم تشغيل مُنشئي الفئات، وتجاوزات readObject، ومُحررات النهائيات أثناء إلغاء التسلسل. إذا كانت البايتات المقروءة تأتي من مصدر غير موثوق، يمكن للمهاجم تشكيلها لتفعيل استدعاءات طرق عشوائية من خلال سلسلة من الفئات الشرعية الموجودة بالفعل في JVM. تُعرف هذه التسلسلات باسم سلاسل الأدوات (gadget chains).
لا تتطلب سلاسل الأدوات إدخال أي تعليمات برمجية جديدة إلى التطبيق. إنها تستغل توصيلات فئات المكتبات الموجودة التي تؤدي طرقها العادية، عند استدعائها بالترتيب الصحيح أثناء إلغاء التسلسل، في النهاية إلى مغسلة مثل Runtime.exec(). توجد أدوات مثل ysoserial خصيصًا لتوليد هذه الحمولات للمكتبات المنشورة على نطاق واسع مثل Apache Commons Collections و Spring Framework وغيرها.
H2 هي قاعدة بيانات علائقية مدمجة نقية بلغة Java. تحدد نوع عمود SQL خاص يسمى OTHER يعمل كمرور عابر لكائنات Java عشوائية. عندما يخزن H2 قيمة في عمود OTHER، فإنه يكتب البايتات التي ينتجها ObjectOutputStream في Java. عندما يعيد قراءة القيمة، يستدعي ObjectInputStream.readObject() لإعادة بناء الكائن. يمكن أيضًا توفير البايتات المتسلسلة الخام مباشرة في استعلام باستخدام بناء جملة النص الست عشري الخاص بـ H2:
SELECT CAST(X'ACED0005...' AS OTHER);
-- أو
SELECT X'ACED0005...'::OTHER;
البادئة ACED متبوعة بـ 0005 هي الرقم السحري لتيار تسلسل Java وإصدار البروتوكول. أي سلسلة ست عشرية تبدأ بـ ACED0005 هي تيار كائن Java متسلسل.
عندما يقوم H2 بمعالجة هذا الاستعلام، فإنه يقوم بإلغاء تسلسل البايتات الست عشرية على جانب قاعدة البيانات. يتم بعد ذلك تمرير الكائن الناتج مرة أخرى إلى التطبيق المُستدعٍ من خلال ResultSet الخاص بـ JDBC. إذا فحص التطبيق قيمة العمود — على سبيل المثال، لتنسيقه للعرض — فقد يؤدي ذلك إلى معالجة إضافية. هذا هو بالضبط ما يفعله Metabase في مسار التعليمات البرمجية الثغرة.
يتلقى Metabase كائن ResultSet من برنامج تشغيل JDBC الخاص بـ H2 ويفحص بيانات تعريف الأعمدة ليقرر كيفية عرض كل قيمة للمستخدم. عندما يواجه عمودًا من نوع JDBC Types.OTHER (يُبلغ عنه أيضًا باسم JAVA_OBJECT)، تحاول الإصدارات الثغرة من Metabase إلغاء تسلسل البايتات الخام لإنتاج تمثيل قابل للعرض. يتم تنفيذ استدعاء إلغاء التسلسل هذا، ObjectInputStream.readObject()، دون أي تصفية قائمة بيضاء أو التحقق من الفئة.
تسلسل الأحداث هو:
OTHER يحتوي على حمولة متسلسلة مصممة.JAVA_OBJECT في ResultSet.OTHER ويستدعي readObject() على البايتات.Runtime.exec() وتنفذ أمر المهاجم كمستخدم نظام التشغيل الذي يقوم بتشغيل عملية Metabase.تحل الإصدارات المُصحَّحة المشكلة عن طريق فحص بيانات تعريف نتائج JDBC قبل محاولة أي إلغاء تسلسل. إذا تمت كتابة عمود على أنه JAVA_OBJECT، يرفضه Metabase مباشرة بدلاً من محاولة تحليله.
يتطلب الاستغلال توثيقًا. يجب أن يمتلك المهاجم حساب Metabase مع إذن تنفيذ استعلام أصلي على قاعدة بيانات مدعومة بـ H2. حسابات المسؤول تلبي هذا افتراضيًا. يمكن لحسابات المستخدمين العادية أيضًا تلبية هذا المطلب إذا كان المسؤول قد منحهم إذن البيانات للاستعلامات الأصلية لقاعدة البيانات ذات الصلة.
أزال Metabase دعم إضافة H2 كاتصال جديد بمستودع البيانات في الإصدار 0.46.6.4، الذي تم إصداره في عام 2023. محاولة تسجيل اتصال H2 جديد من خلال واجهة المسؤول تُعيد الخطأ "H2 غير مدعوم كمستودع بيانات." كان هذا الإزالة استجابة لثغرات سابقة متعلقة بـ H2 وكان يهدف إلى القضاء على خطر الاتصال بمثيلات H2 التي يسيطر عليها المهاجم.
ومع ذلك، فإن إزالة H2 من واجهة اتصال مستودع البيانات ليس هو نفس إزالة H2 من Metabase. لا يزال هناك قاعدتا بيانات H2 موجودتان في كل تثبيت افتراضي لـ Metabase.
الأولى هي قاعدة بيانات التطبيق. عندما لا يتم تكوين Metabase لاستخدام قاعدة بيانات خارجية مثل PostgreSQL أو MySQL، فإنه يخزن بياناته الوصفية — الأسئلة ولوحات المعلومات وحسابات المستخدمين والإعدادات — في ملف H2 في /metabase-data/metabase.db.mv.db. لا يمكن الاستعلام عن قاعدة البيانات هذه مباشرة من خلال واجهة المستخدم الخاصة بـ Metabase.
الثانية، والأكثر قابلية للاستغلال مباشرة، هي قاعدة البيانات التجريبية. أثناء الإعداد الأولي، يقوم Metabase بإنشاء قاعدة بيانات H2 معبأة مسبقًا ببيانات نموذجية ويجعلها متاحة كاتصال "قاعدة البيانات التجريبية". هذا الاتصال موجود افتراضيًا في كل مثيل Metabase وهو سطح الهجوم الأساسي لـ CVE-2026-59827. إنه اتصال H2 مباشر يمكن للمستخدمين تشغيل استعلامات SQL أصلية ضده، وسلسلة الاتصال الظاهرة في لوحة المسؤول تشير إلى file:/plugins/sample-database.db.