
مختبر قائم على Docker لإعادة إنتاج CVE-2026-42647، وهو حقن SQL أعمى زمني غير مصادق عليه في إضافة JoomSport لووردبريس عبر باراميتر sortf. يتضمن أهدافًا ضعيفة ومصحوبة للمقارنة.
sortfيحتوي هذا المستودع على بيئة مختبر Docker محلية لإعادة إنتاج والتحقق من صحة CVE-2026-42647، وهي ثغرة حقن SQL بدون مصادقة تؤثر على إضافة WordPress JoomSport - للرياضات: الفريق والدوري، كرة القدم، الهوكي، والمزيد.
يحدث السلوك القابل للاختراق في ميزة فرز قائمة اللاعبين. يمكن للزائر العام التحكم في معامل الاستعلام sortf، والذي يُستخدم لبناء جملة SQL ORDER BY. في الإصدارات الضعيفة، يتم تنظيف القيمة كنص وتغليفها بعلامات backticks، ولكن لا يتم التحقق منها مقابل قائمة مسموح بها صارمة قبل إلحاقها باستعلام SQL.
يقارن هذا المختبر إصدارين من JoomSport:
| الخدمة | إصدار JoomSport | الغرض | الرابط |
|---|---|---|---|
vuln | 5.7.6 | هدف المقارنة الضعيف | http://localhost:8081 |
patched | 5.7.8 | هدف المقارنة المُصحَّح | http://localhost:8082 |
تحدد الإشعارات العامة الإصدارات قبل 5.7.8 بأنها متأثرة و5.7.8 كالإصدار المُصحَّح. يستخدم هذا المختبر 5.7.6 كهدف ضعيف لأنه لم يكن هناك علامة مصدر 5.7.7 متاحة في قائمة علامات SVN لإضافة WordPress.org في وقت إعداد هذا المختبر.
سلسلة الثغرات الموضحة هي:```text Unauthenticated visitor → JoomSport season player list route → attacker-controlled sortf parameter → unsafe dynamic ORDER BY construction → SQL expression execution → measurable database delay in vulnerable version → patched version rejects the injected sort field and falls back to a safe allowlisted field
هذا المختبر يتحقق من الثغرة على أنها حقن SQL أعمى قائم على الوقت. لا يقوم بتفريغ قاعدة البيانات، استخراج بيانات الاعتماد، تعديل البيانات، أو عمليات SQL تخريبية.
تم تصميم هذا المختبر للبحث المحلي المتحكم فيه، والفهم على مستوى المصدر، والعرض التوضيحي للمحفظة فقط.
## حقائق مؤكدة
| الادعاء | الدليل | كيفية التحقق في هذا المختبر |
| ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| تم الإبلاغ عن أن JoomSport قبل الإصدار 5.7.8 معرض لحقن SQL غير مصادق عليه. | تحدد الإعلانات العامة أن JoomSport `< 5.7.8` / `<= 5.7.7` متأثر. | راجع قسم المراجع وقارن بين الخدمات المعرضة والمصححة. |
| الإصدار 5.7.8 من JoomSport هو الإصدار المُصلح. | تظهر الإعلانات العامة ومقارنة المصدر أن الإصدار 5.7.8 يتحقق من قيمة `sortf` قبل بناء تعبير الترتيب. | افحص `class-jsport-playerlist.php` في كلا الإصدارين. |
| المعامل المتأثر هو `sortf`. | يقرأ كود قائمة اللاعبين المعرض `classJsportRequest::get('sortf')`. | قم بتشغيل PoC ولاحظ طلب `sortf` المحقون. |
| الكود المعرض يبني قيمة ترتيب SQL ديناميكية من إدخال المستخدم. | في الإصدار المعرض، يتم استخدام `sortf` لبناء `$options['ordering']`. | افحص `sportleague/classes/objects/class-jsport-playerlist.php`. |
| مصرف SQL هو جملة `ORDER BY`. | يتم إلحاق قيمة `$ordering` الناتجة لاحقًا في استعلام SQL مع `ORDER BY`. | افحص `sportleague/base/wordpress/classes/class-jsport-getplayers.php`. |
| التصحيح يستخدم إصلاحًا من نمط القائمة البيضاء. | يقدم الإصدار المُصلح أعمدة ثابتة مسموح بها وأنماط حقل ديناميكية متوقعة قبل استخدام حقل الفرز. | قارن بين كود JoomSport 5.7.6 و 5.7.8. |
| يوضح المختبر حقن SQL أعمى قائم على الوقت. | يتأخر الهدف المعرض عند استخدام تعبير `SLEEP()` محقون؛ الهدف المُصلح لا يتأخر. | قم بتشغيل `python3 poc/poc.py http://localhost:8081 http://localhost:8082`. |
## الافتراضات والمجهولات
يستخدم هذا المختبر JoomSport 5.7.6 كهدف مقارنة معرض لأن الإصدار المُصلح العام هو 5.7.8 ولم يكن علامة مصدر 5.7.7 متوفرة في قائمة علامات SVN لملحق WordPress.org عند إعداد المختبر.
لا يدعي المختبر أن الإصدار 5.7.6 هو الإصدار المعرض الوحيد. يتم استخدامه كخط أساس معرض قابل للتكرار لمقارنة السلوك المعرض مقابل سلوك 5.7.8 المُصلح.
يركز المختبر على معامل `sortf` في تدفق فرز قائمة اللاعبين.
التأثير الموضح هو حقن SQL أعمى قائم على الوقت. لا يوضح المختبر:
* تفريغ قاعدة البيانات مباشرة،
* استخراج بيانات الاعتماد،
* تجاوز المصادقة،
* تصعيد الامتيازات،
* تعديل البيانات التعسفي،
* تنفيذ التعليمات البرمجية عن بعد،
* الاستمرارية،
* الاستدعاءات الخارجية،
* أو هجمات ضد أنظمة غير مختبرية.
قد يكون السلوك القائم على الأخطاء أو القائم على القيم المنطقية ممكنًا اعتمادًا على سلوك قاعدة البيانات، تكوين التطبيق، واختلافات الاستجابة، لكن هذا المختبر لا يعتمد على تلك التقنيات. الدليل الأساسي هو قائم على التوقيت.
## ملخص السبب الجذري
السبب الجذري هو بناء غير آمن لجملة `ORDER BY` SQL ديناميكية من معامل الطلب `sortf`.
يبدأ مسار الكود المعرض في:```text
sportleague/classes/objects/class-jsport-playerlist.php
داخل منطق تحميل قائمة اللاعبين، يقرأ JoomSport معامل الطلب:```text sortf
ويستخدمه لبناء:```text
$options['ordering']
نمط المصدر الضعيف ذو الصلة هو:```php
if (classJsportRequest::get('sortf')) {
$typeAD = in_array(classJsportRequest::get('sortd'), array("ASC","DESC")) ? classJsportRequest::get('sortd') : "ASC";
$options['ordering'] = str_replace(" ","",sanitize_text_field("".classJsportRequest::get('sortf')."")).' '.$typeAD;
}
المشكلة ليست في المقام الأول في المعامل `sortd`. قيمة `sortd` مقيدة بـ:```text
ASC
DESC
المشكلة هي معامل sortf لأنه يتحكم في موضع معرف/تعبير SQL المستخدم للترتيب.
التعبير الخطير هو:```php
"".classJsportRequest::get('sortf').""
يقوم الكود بوضع إدخال يتحكم فيه المهاجم داخل سياق معرف MySQL ثم يمرره إلى الأمام كجزء من ترتيب SQL.
يطبق الكود:```php
sanitize_text_field()
لكن sanitize_text_field() ليس تحققًا من معرفات SQL. إنه مصمم لتنظيف النص، وليس لبناء جملة SQL بأمان.
كما أن الكود الضعيف يحيط حقل الفرز الذي يتحكم به المستخدم بعلامات التنصيص الخلفية (backticks). ومع ذلك، فإن علامات التنصيص الخلفية ليست حدودًا أمنية عندما يتمكن المهاجم من التأثير على محتوى المعرف. إذا تمكن المهاجم من حقن علامة تنصيص خلفية في القيمة، فيمكنه الخروج من سياق المعرف المقصود.
يتم تمرير قيمة الترتيب المُنشأة لاحقًا إلى استعلام استرجاع اللاعب وتُلحق في جملة SQL ORDER BY في:```text
sportleague/base/wordpress/classes/class-jsport-getplayers.php
نمط المصب هو:```php
$query .= ' ORDER BY '.($ordering);
هذا ينشئ تدفق البيانات الضعيف:```text sortf request parameter → classJsportRequest::get('sortf') → $options['ordering'] → $ordering → ORDER BY
المشكلة الأمنية هي أن التطبيق يعامل معامل طلب يتحكم فيه المستخدم كمحدد/تعبير SQL دون التحقق منه أولاً مقابل قائمة مسموح بها صارمة.
## ملخص التصحيح المصدر
التصحيح ذو الصلة موجود في:```text
sportleague/classes/objects/class-jsport-playerlist.php
في الإصدار الضعيف، يقوم كود قائمة اللاعبين ببناء $options['ordering'] مباشرة من قيمة الطلب:```php
if (classJsportRequest::get('sortf')) {
$typeAD = in_array(classJsportRequest::get('sortd'), array("ASC","DESC")) ? classJsportRequest::get('sortd') : "ASC";
$options['ordering'] = str_replace(" ","",sanitize_text_field("".classJsportRequest::get('sortf')."")).' '.$typeAD;
}
الجزء المعرض للخطر هو أن `classJsportRequest::get('sortf')` يُستخدم داخل تعبير ترتيب SQL.
يقوم JoomSport 5.7.8 بتغيير هذا السلوك عن طريق تقديم متغير حقل فرز تم التحقق منه قبل بناء `$options['ordering']`.