דילוג לתוכן המרכזי
מודול 8 · שיעור 4 מתוך 432/32 בקורס~14 min
שיעורי מודול (4/4)

כתיבת תבניות בטוחות ב-ReDoS

ReDoS (מניעת שירות של ביטוי רגיל) הוא סוג של התקפות שבהן קלט מעוצב בקפידה גורם לזמן ההתאמה של ביטוי רגיל להתפוצץ. מנוע JS משתמש ב-backtracking: אם דפוס הוא "דו-משמעי", ב-an קלט חסר מזל זה יכול לבצע מספר אקספוננציאלי של ניסיונות.

הדפוס הקטסטרופלי הקלאסי

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 ניסיונות