
ثغرة XSS انعكاسية غير مصادَق عليها في WPForms <= 2.0.2.1 — تجاوز تهريب Smart Tag الخاص بـ CVE-2026-88996 في موضع اسم السمة
المتأثر: WPForms – AI Form Builder for WordPress (النسخة المجانية/المخففة)، الإصدار 2.0.2.1 — وهو أحدث إصدار حالي وقت الإفصاح (وهو أيضًا الإصدار الذي يحتوي على إصلاح CVE-2026-88996). تشترك نسخة Pro في مُصيّر Smart Tag.
التصنيف: برمجة نصية عبر المواقع منعكسة غير مصادق عليها (CWE-79) مع تنفيذ JavaScript مُتحقَّق منه، عبر إصلاح غير مكتمل لـ CVE-2026-88996 / GHSA-8j5g-9vmv-9mmw.
تاريخ الاكتشاف: 2026-09-27 ·
أُبلِغ عنه إلى Patchstack: 2026-09-27 ·
رُفض: 2026-09-28 ("لا تظهر المشكلة إلا عندما يكتب مسؤول الموقع Smart Tag مجرّدًا حيث ينبغي أن يكون اسم سمة HTML... وليس إعدادًا افتراضيًا ولا نمطًا قد يألفه أحد واقعيًا" — لم تُنازَع الصحة التقنية) ·
علني: 2026-09-28.
يُهرّب إصلاح 2.0.2.1 لعائلة CVE-2026-93485 من XSS المنعكس قيم Smart Tag التي
تُستبدَل داخل الترميز (SmartTags::escape_for_attribute() يرمّز علامات الاقتباس
والمسافات البيضاء). وهذا فعّال كلما وقعت القيمة المُستبدَلة داخل قيمة سمة
مُقتبَسة. عندما يضع مؤلف النموذج Smart Tag مجرّدًا في موضع اسم
سمة داخل رسالة التأكيد — على سبيل المثال:
<input {field_id="3"}>
قيمة حقل مُرسَلة لا تحتوي على علامات اقتباس ولا مسافات بيضاء، مثل
onmouseover=alert(1)، تُدرَج حرفيًا وتصبح سمة معالج حدث جديدة ونشطة.
لا يقوم التهريب أبدًا بترميز =، وأسماء السمات لا تتطلب علامات اقتباس ولا
مسافات بيضاء. ثم يحتوي التأكيد المُعاد إلى المُرسِل المجهول على:
<input onmouseover=alert(1)>
تُعدّ عمليات الإرسال المجهولة إلى admin-ajax.php (action=wpforms_submit، wp_ajax_nopriv_*) خالية من nonce بحكم التصميم للمستخدمين غير المسجّلين، لذا فإن هذا XSS منعكس غير مُصادَق بالكامل. يُنفَّذ JavaScript عشوائي ضمن قيد الرمز الواحد عبر onmouseover=eval(String.fromCharCode(...)).
في النموذج نفسه، يُهرَّب شكل حمولة CVE الأصلية — كسر علامة الاقتباس من داخل قيمة مُقتبسة، مثل x" onfocus=alert(1) autofocus y=" — بشكل صحيح في كل موضع (لوحظ ترميز " /  ). يعمل التهريب في 2.0.2.1 في كل مكان باستثناء موضع اسم السمة. هذا إصلاح غير مكتمل لنفس مصرف الاستبدال، وليس فجوة ميزة منفصلة.
# 1. WordPress + WPForms lite 2.0.2.1, create a form with a single-line text field (id 3)
# 2. Set the form's Confirmation message to:
# A: <input value="{field_id="3"}"> B: <input {field_id="3"}>
# 3. Run the PoC (stdlib-only Python 3):
python3 poc.py --url http://target.example/form-page/
لا يوجد محتوى مُدخل للترجمة. يرجى تزويدي بالنص المطلوب ترجمته (الجزء السابع من تسعة).
[+] field 3 reflects into the confirmation message
[payload (bypass position)] occurrences: LIVE=1 ESCAPED/INERT=2
LIVE -> ...<input onmouseover=alert(poc93485)>...
[control] parent-CVE payload escaped everywhere: YES (fix works at value positions)
=== VERDICT: VULNERABLE — payload reaches attribute-NAME position unescaped ===
poc.py يكتشف تلقائيًا النموذج والحقول والحقل العاكس؛ ويُرسل بشكل مجهول؛ ويُصنّف كل تكرار على أنه LIVE (حقن اسم السمة) مقابل ESCAPED (قيمة مُقتبسة، شكل CVE الأصلي). رمز الخروج 0 = قابل للاستغلال.
يجب أن تحتوي رسالة التأكيد التي كتبها المسؤول في النموذج على Smart Tag عاكس للإدخال عاري داخل الترميز في موضع اسم السمة. قيّم باحثو Patchstack ذلك كنمط تأليف غير واقعي؛ ومع ذلك فهو موضع ميزة موثّق، والتهريب موجود تحديدًا لجعل الاستبدال في سياق الترميز آمنًا، ولا يتلقى المؤلف أي خطأ — فقط حقن صامت.
ترميز = في تهريب سياق الترميز، أو تحليل ترميز التأكيد سياقيًا والسماح باستبدال Smart Tag فقط في مواضع النص وقيم السمات المُقتبسة.
poc.py — إثبات مفهوم مكتفٍ ذاتيًا (لا خطوات من جانب الخادم، لا تبعيات)poc.sh — نسخة مصغّرة قائمة على curlلأغراض الاختبار المصرّح به والتعليم فقط. ينشر المُبلّغ هذا بعد رفض محاولة إرسال منسّقة؛ ولم يتم الطعن في النتيجة التقنية.
Ashish Kunwar (@D0rkerdevil)