الانتقال إلى المحتوى الرئيسي
الوحدة 8 · الدرس 4 من 432/32 في الدورة~14 min
دروس الوحدة (4/4)

كتابة أنماط ReDoS الآمنة

ReDoS (التعبير العادي لرفض الخدمة) هي فئة من الهجمات حيث المدخلات المصممة بعناية تجعل وقت المطابقة للتعبير العادي ينفجر. يستخدم محرك JS التراجع: إذا كان النمط "غامضًا"، على المدخلات غير المحظوظة يمكنها إجراء عدد هائل من المحاولات.

النمط الكارثي الكلاسيكي

Code
Pattern: ^(a+)+$
Input:   "aaaaaaaaaaaaaaaaaaaaab"

للمطابقة، يحاول المحرك كل قسم ممكن من "a" بينهما المحددين الكميين +. في 20 "a" يكون ذلك 2^20 = ~1 مليون محاولة. في 30 "أ"، مليار.

أمثلة خطيرة أخرى:

  • (a*)*b -- "النجوم المتداخلة".
  • (a|a)* -- البدائل المتداخلة.
  • (\w+)+@ -- المجموعات الجشعة ذات مُحدِّد كمية خارجي.

كيفية اكتشاف الخطر

ابحث عن هذه الهياكل:

  1. محدد الكمية داخل محدد الكمية: (...+)+، (...*)*، (...{n,})+.
  2. البدائل المتداخلة تحت مُحدِّد الكمية: (a|ab)*، ​​(\w|\d)+.
  3. النظر إلى الأمام/النظر إلى الخلف باستخدام البدائل المعقدة المتكرر.

إعادة الكتابة الدفاعية

Code
Dangerous:  ^(\w+\s+)+$
Safe:       ^(?:\w+\s+)*\w+$

الإصدار الآمن ** يفصل ** الحالة الأساسية عن الحالة المتكررة، ويزيلها الغموض. تقنيات أخرى:

  • محددات الكمية (a++) - غير مدعومة في JS، ولكنها متوفرة في المحركات الأخرى.
  • الأنماط الذرية ((?>...)) -- ليست في JS.
  • حدد طول الإدخال قبل المطابقة.
  • مهلة عند المطابقة (يستخدم محرر هذه الدورة عاملاً لديه مهلة قدرها 500 مللي ثانية).

توصيات لأنماط ReDoS الآمنة

  1. تأكد من أن الخيارات بالتناوب متنافية (على سبيل المثال، لا تستخدم (a|a+)).
  2. تجنب تطبيق محددات الكمية المتداخلة على التعبيرات المتداخلة (على سبيل المثال (\\s*)*).
  3. تفضل دائمًا فئات الأحرف المحددة ([^\\n]*) على نقطة البدل العامة (.*).

جربه

تمرين#regex.m8.l4.e1
المحاولات: 0جارٍ التحميل…

التعرف على أنماط الحروف المتكررة - ولكن بطريقة آمنة لـ ReDoS. استخدم فئة أحرف واحدة، وليس مجموعات متداخلة مثل (a+)+.

جارٍ تحميل المحرر…
إظهار التلميح

استبدل الخطورة (a+)+ بـ a+ البسيط. والنتيجة هي نفسها، ولكنها آمنة.

الحل متاح بعد 3 من المحاولات

تمرين المراجعة

تمرين#regex.m8.l4.e2
المحاولات: 0جارٍ التحميل…

التعرف على سلسلة من الكلمات مفصولة بمسافات، بطريقة آمنة لـ ReDoS. استخدم البنية `(?:word+spaces+)*word` بدلاً من `(word+space+)+`.

جارٍ تحميل المحرر…
إظهار التلميح

استبدل مجموعة الالتقاط (\\w+\\s+)+ بالإصدار المنفصل (?:\\w+\\s+)*\\w+.

الحل متاح بعد 3 من المحاولات

التحدي الإضافي

تمرين#regex.m8.l4.e3
المحاولات: 0جارٍ التحميل…

Make the vulnerable pattern `(\w+\s*)+:` which causes ReDoS safe, by removing the overlapping whitespace recursion.

جارٍ تحميل المحرر…
إظهار التلميح

انقل المسافة بحيث لا تتداخل مع تكرار المجموعة: (?:\\w+\\s+)*\\w+:

الحل متاح بعد 3 من المحاولات