
تخصيص الموارد دون حدود أو تقييد في مكوّن تحميل الأوزان HDF5 في Google Keras من الإصدار 3.0.0 حتى 3.13.0 على جميع المنصات يسمح لمهاجم عن بُعد بالتسبب في رفض الخدمة (DoS) من خلال استنزاف الذاكرة وتعطل مترجم Python عبر ملف .keras مُصمَّم خصيصًا.
| الحقل | التفاصيل |
|---|---|
| CVE ID | CVE-2026-0897 |
| الحزمة | keras (Google Keras) |
| السجل | PyPI |
| الإصدارات المتأثرة | 3.0.0 إلى 3.13.0 (ضمناً) |
| نوع الثغرة | CWE-770: تخصيص الموارد دون حدود أو تحديد |
| درجة CVSS | 7.1 عالية (CVSS 4.0، CNA: Google Inc.) |
| متجه CVSS | CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N |
| متجه الهجوم | شبكة |
| تعقيد الهجوم | منخفض |
| الصلاحيات المطلوبة | لا شيء |
| تفاعل المستخدم | سلبي (الضحية يحمل ملف نموذج) |
| تأثير التوفر | عالي |
| تأثير السرية | لا شيء |
| تأثير النزاهة | لا شيء |
| تاريخ نشر NVD | 15 يناير 2026 |
| آخر تعديل NVD | 23 يناير 2026 |
| المصدر / CNA | Google Inc. |
| أبلغ بواسطة | HyperPS (Sarvesh Patil) عبر huntr.dev / GHSA |
| حالة الإصلاح | تم الدمج — PR #21880 |
توجد ثغرة أمنية في رفض الخدمة في مكون تحميل أوزان HDF5 في Google Keras الإصدارات 3.0.0 إلى 3.13.0 على جميع المنصات. تحدث الثغرة بسبب غياب أي تحقق أو تقييد عند معالجة بيانات شكل مجموعة بيانات HDF5 المُعلنة داخل أرشيف .keras.
يسمح تنسيق HDF5 لمجموعات البيانات بتعريف شكلها (أبعاد الموتر) كبيانات وصفية. عندما يقوم Keras بتحميل أوزان النموذج من أرشيف .keras، فإنه يقرأ هذا الشكل المُعلن ويحاول تخصيص كتلة ذاكرة مقابلة قبل نقل أي بيانات. ونظرًا لأن Keras لا يقوم بإجراء فحص للحدود على الشكل المُعلن قبل التخصيص، يمكن للمهاجم إنشاء ملف model.weights.h5 يعلن عن شكل ضخم فلكيًا — على سبيل المثال (1000000, 1000000, 1000000)، مما يؤدي إلى محاولة Keras تخصيص ذاكرة بحجم بيتابايت. هذا يستنزف كل ذاكرة النظام المتاحة ويعطل مترجم Python.
لا يلزم أي استدلال أو تفاعل إضافي بعد تحميل النموذج. يتم تفعيل الهجوم بالكامل في وقت التحميل.
| الملف | الوصف |
|---|---|
keras/src/saving/file_editor.py | KerasFileEditor._extract_weights_from_store() — يقرأ شكل مجموعة بيانات HDF5 ويخصص الذاكرة دون التحقق من الحجم أو التقييد |
تقع الثغرة تحديدًا في فئة KerasFileEditor، المسؤولة عن إلغاء تسلسل موترات أوزان النموذج من مخازن HDF5 المضمنة داخل أرشيفات .keras.
.keras من مصادر غير موثوقة أو مقدمة من المستخدم يكون عرضة للخطريخزن تنسيق ملف HDF5 البيانات الوصفية للموتر — بما في ذلك تعريفات الشكل — بشكل منفصل عن بايتات البيانات الفعلية. عندما يواجه KerasFileEditor._extract_weights_from_store() إدخال مجموعة بيانات، فإنه يقرأ الشكل المُعلن ويستدعي NumPy لتخصيص مصفوفة مسبقًا بالأبعاد المقابلة قبل قراءة أي بيانات من القرص.
نظرًا لأن الشكل هو بيانات وصفية، يمكن لملف HDF5 صغير جدًا أن يعلن عن شكل يتطلب بيتابايت من الذاكرة بينما يظل الملف نفسه بحجم كيلوبايت فقط. تجعل نسبة حجم الملف إلى حجم التخصيص هذا هجوم تضخيم فعال للغاية.
شكل مثل (1000000, 1000000, 1000000) بنوع بيانات float32 سيطلب حوالي 4000 بيتابايت من الذاكرة. سيقوم قاتل نفاد الذاكرة لنظام التشغيل أو موزع Python بتعطيل العملية على الفور تقريبًا.
# keras/src/saving/file_editor.py (pre-fix, simplified)
def _extract_weights_from_store(self, h5_file, inner_path=""):
for key in h5_file.keys():
obj = h5_file[key]
if isinstance(obj, h5py.Dataset):
# Shape is read from metadata — no validation performed
shape = obj.shape
# NumPy attempts to allocate based on declared shape
data = np.zeros(shape, dtype=obj.dtype) # VULNERABLE: unbounded allocation
غياب أي فحص على shape قبل استدعاء np.zeros() هو السبب الجذري.
هذه المعلومات مقدمة للأغراض التعليمية والدفاعية فقط. لا تختبر ضد أنظمة لا تملكها أو ليس لديك إذن صريح لاختبارها.
.keras خبيث# generate_shape_bomb.py
import h5py
import zipfile
import json
import os
# Step 1: Create a minimal HDF5 weights file with a hostile shape declaration
with h5py.File("model.weights.h5", "w") as f:
grp = f.create_group("layers/dense/vars")
# Declare shape that would require petabytes of memory to allocate
# Actual data is never written — only the metadata shape declaration is malicious
grp.create_dataset(
"0",
shape=(0,), # actual stored data: empty
maxshape=(None,),
dtype="float32",
data=[]
)
# Override shape metadata to declare hostile dimensions
# (achieved via direct HDF5 attribute manipulation in a real attack)
# Step 2: Package into a valid .keras archive structure
config = {
"class_name": "Sequential",
"config": {"name": "sequential", "trainable": True, "layers": []},
"keras_version": "3.0.0",
"backend": "tensorflow"
}
with zipfile.ZipFile("malicious_model.keras", "w") as zf:
zf.writestr("config.json", json.dumps(config))
zf.writestr("model.weights.h5", open("model.weights.h5", "rb").read())
print("[+] Malicious .keras archive generated: malicious_model.keras")
# trigger.py
import keras
print("[+] Loading malicious model...")
# The crash occurs at load time — no inference required
model = keras.saving.load_model("malicious_model.keras")
print("[-] This line is never reached — interpreter has crashed")
النتيجة المتوقعة: يتوقف مترجم Python مع MemoryError أو يتم قتله بواسطة معالج نفاد الذاكرة لنظام التشغيل قبل اكتمال التحميل.
الأعراض المرئية:
MemoryError أثناء load_model() أو load_weights()h5dumpتم حل الثغرة بواسطة الباحث (HyperPS / Sarvesh Patil) في PR #21880، الذي تم دمجه في keras-team:master في 29 ديسمبر 2025، وتمت مراجعته والموافقة عليه من قبل مشرف Keras hertschuh.
| المورد | الرابط |
|---|---|
| طلب السحب للإصلاح | https://github.com/keras-team/keras/pull/21880 |
يقوم التصحيح بتعديل KerasFileEditor._extract_weights_from_store() في keras/src/saving/file_editor.py لإضافة الحمايات التالية قبل أي تخصيص ذاكرة:
inner_path أثناء الاجتياز التكراري لمخزن HDF5الإصلاح متوافق مع الإصدارات السابقة مع جميع ملفات أوزان Keras الصالحة.
# keras/src/saving/file_editor.py (post-fix logic, simplified)
MAX_BYTES = 1 * 1024 ** 3 # 1 GiB hard cap per dataset
MAX_RANK = 64
def _validate_hdf5_dataset_shape(shape, dtype):
"""Reject hostile HDF5 shape declarations before any allocation."""
if len(shape) > MAX_RANK:
raise ValueError(
f"HDF5 dataset has rank {len(shape)}, which exceeds the "
f"maximum permitted rank of {MAX_RANK}. This may indicate "
"a malicious file."
)
for dim in shape:
if dim < 0:
raise ValueError(
f"HDF5 dataset contains a negative dimension ({dim}). "
"This may indicate a malicious file."
)
import math, numpy as np
try:
total_elements = math.prod(shape)
except OverflowError:
raise ValueError(
"HDF5 dataset shape overflows integer arithmetic. "
"This may indicate a malicious file."
)
itemsize = np.dtype(dtype).itemsize
total_bytes = total_elements * itemsize
if total_bytes > MAX_BYTES:
raise ValueError(
f"HDF5 dataset would require {total_bytes / 1024**3:.2f} GiB to "
f"load, which exceeds the 1 GiB safety limit. This may indicate "
"a malicious file."
)
الترقية عبر pip:
pip install --upgrade keras
التحقق من الإصدار المثبت:
python -c "import keras; print(keras.__version__)"
المسح المسبق لملف وزن HDF5 بحثًا عن أشكال مشبوهة:
h5dump --header model.weights.h5 | grep -i "DATASPACE"
يوثق هذا المستودع CVE-2026-0897 بدقة للأغراض التعليمية والبحثية والأمنية الدفاعية. يتم توفير كود إثبات المفهوم والتفاصيل الفنية لمساعدة المطورين ومهندسي الأمن ومسؤولي الأنظمة في فهم وتقييم ومعالجة هذه الثغرة.
أي استخدام لهذه المعلومات لإلحاق الضرر بالأنظمة أو الخدمات أو الأفراد دون إذن صريح هو غير قانوني وغير أخلاقي. لا يتحمل المؤلف أي مسؤولية عن سوء استخدام المعلومات الواردة هنا.
المساهمون @mohitf070304
| المقياس | القيمة | المعنى |
|---|
| متجه الهجوم (AV) | شبكة | قابل للاستغلال عن بُعد عبر ملف نموذج موزع |
| تعقيد الهجوم (AC) | منخفض | لا توجد شروط خاصة أو شروط سباق مطلوبة |
| متطلبات الهجوم (AT) | لا شيء | لا حاجة لتكوين نشر مسبق |
| الصلاحيات المطلوبة (PR) | لا شيء | لا حاجة لمصادقة أو حساب |
| تفاعل المستخدم (UI) | سلبي | يجب على الضحية تحميل أرشيف .keras خبيث |
| توفر النظام المتأثر (VA) | عالٍ | مترجم Python يتعطل؛ تصبح الخدمة غير متاحة تمامًا |
| سرية النظام المتأثر (VC) | لا شيء | لا تسريب بيانات |
| نزاهة النظام المتأثر (VI) | لا شيء | لا تعديل بيانات |
| تأثير النظام اللاحق (SC/SI/SA) | لا شيء | الأثر محصور في عملية التحميل |
| السياق | المخاطرة |
|---|
واجهات برمجة التطبيقات العامة لخدمة النماذج التي تقبل ملفات .keras المرفوعة من المستخدمين | المهاجم يعطل خدمة الاستدلال بطلب واحد |
| منصات التعلم الآلي التي تستضيف تنزيلات النماذج المجتمعية (مثل Hugging Face) | نموذج مسموم يسبب رفض الخدمة لأي باحث يقوم بتنزيله وتحميله |
| بيئات التعلم الموحد | مشارك خبيث يوزع ملف وزن معد لتعطيل المنسق أو العقد النظيرة |
| خطوط أنابيب CI/CD التي تحمل نقاط تفتيش النماذج | نقطة تفتيش مخترقة أو مستبدلة تسبب فشل خط الأنابيب وعدم توفره |
| روبوتات الدردشة أو خدمات NLP التي تعيد تحميل النماذج في وقت التشغيل | طلب إعادة تحميل خبيث واحد يؤدي إلى تعطيل الخدمة |
| الالتزام المدمج | 7360d4f |
| طلب النقل العكسي (3.12.x) | Issue #22031 |
| الإجراء | التفاصيل |
|---|
| ترقية Keras | التحديث إلى إصدار يتضمن الإصلاح من PR #21880 (إصدارات master بعد 3.13.0 أو أي إصدار رسمي مصحح) |
| لا تقم بتحميل ملفات نماذج غير موثوقة | لا تقم مطلقًا بتحميل ملفات .keras أو .weights.h5 من مواقع غير موثوقة أو غير موثقة أو من مصادر مجتمعية دون التحقق من السلامة مسبقًا |
| التحقق من سلامة الملف | التحقق من مجاميع SHA-256 لأرشيفات النماذج مقابل التجزئات التي يوفرها الناشر قبل التحميل |
| المسح المسبق باستخدام h5dump | استخدم h5dump --header <file> لفحص بيانات شكل مجموعة البيانات في ملفات HDF5 قبل تحميلها في Keras |
| أقل صلاحية | تشغيل عمليات خدمة النماذج تحت مستخدم نظام مقيد بحدود ذاكرة يتم فرضها عبر cgroups أو ulimit لتقييد نطاق الانفجار |
| الحاوية | عزل تحميل النموذج في حاوية محصنة بحدود ذاكرة لمنع تعطل واحد من التأثير على الخدمات الأخرى |
| مراقبة الذاكرة | مراقبة عمليات تحميل النموذج للتنبيه على أنماط تخصيص الذاكرة غير الطبيعية |
| التاريخ | الحدث |
|---|
| 29 نوفمبر 2025 | تقديم طلب السحب للإصلاح PR #21880 إلى keras-team/keras بواسطة HyperPS |
| 1 ديسمبر 2025 | مشرف Keras hertschuh يطلب مراجع؛ تبدأ المراجعة |
| 26 ديسمبر 2025 | اكتمال مراجعة المشرف؛ معالجة الملاحظات النهائية |
| 29 ديسمبر 2025 | الموافقة على PR #21880 ودمجه في keras-team:master |
| 15 يناير 2026 | نشر CVE-2026-0897 على NVD |
| 19 يناير 2026 | فتح طلب النقل العكسي إلى Keras 3.12.x (Issue #22031) |
| 23 يناير 2026 | آخر تعديل لسجل NVD |
| المورد | الرابط |
|---|
| إدخال NVD | https://nvd.nist.gov/vuln/detail/CVE-2026-0897 |
| سجل CVE الرسمي | https://cve.org/CVERecord?id=CVE-2026-0897 |
| تنبيه GitHub (GHSA) | https://github.com/advisories/GHSA-xfhx-r7ww-5995 |
| طلب السحب للإصلاح | https://github.com/keras-team/keras/pull/21880 |
| الالتزام المدمج | https://github.com/keras-team/keras/commit/7360d4f0d764fbb1fa9c6408fe53da41974dd4f6 |
| طلب النقل العكسي | https://github.com/keras-team/keras/issues/22031 |
| Keras على PyPI | https://pypi.org/project/keras/ |
| CWE-770 | https://cwe.mitre.org/data/definitions/770.html |
| توثيق تنسيق HDF5 | https://www.hdfgroup.org/solutions/hdf5/ |