פוסט זה מניח שאתם יודעים ומכירים XSS – אם לא – הפוסט הזה שכתבתי על XSS יעשה לכם סדר.
העברתי לפני כחודשיים בכנס ReactNext שעוסקת ב-XSS ובבעיות במדיניות CSP שיכולות להתרחש בגלל בחירה בספריות בעייתיות של CSS. אני מאד אוהב את XSS כי זה באמת נושא מורכב שצריך כמה אסטרטגיות כדי להתמודד איתו.
אחת האסטרטגיות שנוקטים בהן היא או לבנות Regex שמבצע סניטציה לבד (לא רעיון טוב בכלל) או לבנות על ה-WAF שיעצור payload זדוני. אם אתם לא יודעים מה זה – אז בגדול WAF, או Web Application Firewall הוא כלי אבטחה המיועד להגן על אתרי/אפליקציות אינטרנט מפני התקפות שונות. בעצם זה סוג של חומה שנמצא בין האתר לבין האינטרנט ומסנן את כל התנועה ובולם תנועות חשודות כך למשל, יש WAFים שיעלו על משהו בסגנון:
?p=<script>alert(1)</script>
בעוד ש-WAF הוא כלי חשוב מאד והכרחי בעולם של היום – אפילו לאתרים קטנים, אסור לבנות על WAF שיעצור לנו XSS. בעוד שמומחי אבטחה יגידו שזה ידע טריוויאלי, אני מודה שלא מעט פעמים קשה לי להסביר את זה למתכנתים. ההסבר הרשמי הוא שאפשר לתפור payloads באופן שאפשר להתחמק מגילוי. כך למשל payload זדוני יכול להיות בלי סקריפט בכלל:
<a onmouseover=alert(1)>whatever</a>
אבל בד״כ קשה לי לשכנע מתכנתים שרגילים לזרוק את כל האבטחה שלהם על WAF ולבנות עליו הבעיה שזו אסטרטגיה אביסלע לא משהו והאמת שכמה ימים לפני כתיבת שורות אלו ינאי אדרי מ-Negev Web Developer פרסם משהו שממש מדגים את זה בערוץ הטלגרם שלו JavaScript weekly, אז הנה – מה לפי דעתכם הקוד הזה עושה? מדובר בקוד ג׳אווהסקריפט ולידי לגמרי אגב:
א="",ב=!א+א,ג=!ב+א,ד=א+{},ה=ב[א++
],ו=ב[ח=א],ט=++ח+א,כ=ד[ח+ט],ב[
כ+=ד[א]+(ד.ד+ד)[א]+ג[ט]+ה+ו+ב[ח]+
כ+ה+ד[א]+ו][כ](ג[א]+ג[ח]+ב[ט
]+ו+ה+"(1)")()
אם תשימו אותו בקונסולה או ב-codepen, אתם תופתעו לגלות שיש פה alert 😇 הטכניקה הזו נקראת ערבול ובעולם ה-UTF8 אנחנו נכנסים לעולם של כאב אם אנו מנסים לנחש את ה-Payload או סומכים על ה-WAF.
רוצים דוגמה נוספת? בטח שכן! הנה – קוד שליטרלי עובד ועושה… רוצים לנחש מה?
𓅂='',𓂀=!𓅂+𓅂,𓁄=!𓂀+𓅂,𓊎=𓅂+{},𓆣=𓂀
[𓅂++],𓊝=𓂀[𓇎=𓅂],𓏢=++𓇎+𓅂,𓆗=𓊎[𓇎+𓏢
],𓂀[𓆗+=𓊎[𓅂]+(𓂀.𓁄+𓊎)[𓅂]+𓁄[𓏢]+𓆣+
𓊝+𓂀[𓇎]+𓆗+𓆣+𓊎[𓅂]+𓊝][𓆗](𓁄[𓅂]+𓁄[
𓇎]+𓂀[𓏢]+𓊝+𓆣+'`𓅂 𓏢 𓂀 𓁄 𓆣 𓊝 𓇎`')``
יש עוד המון דוגמאות כאלו באתר הזה המוקדש לטריקים כאלו. מה שקורה הוא הגדרה של משתנים ב-UTF8 והכנסת ערכים אליהם באופן ערמומי שנראה מחוכם אבל הוא פשוט. אני אנסה להסביר.
למשל בהתחלה יש הגדרה של:
𓅂 = ''; // מחרוזת ריקה
אחרי זה מגדירים את המשתנה 𓂀
𓂀 = !𓅂 + 𓅂; // 'true',
טריק עתיק בג׳אווהסקריפט הופך ערך בוליאני למחרוזת טקסט אם מוסיפים ". במקרה הזה התנאי שלעיל הופך אל:
!'' + ''
השלב הבא הוא להציע משתנה נוסף 𓁄 שהערך שלו יהיה 'false' – שימו לב שזו מחרוזת טקסט, לא הערך הבוליאני
𓁄 = !𓂀 + 𓅂 // 'false'
השלב הבא הוא להגיע למחרוזת טקסט שנקראת [object object] ועושים את זה עם {} ו-" שנכנסים לתוך משתנה 𓊎.
𓊎 = 𓅂 + {};
אחרי שיש לנו כמה מחרוזות טקסט, כל מה שאנחנו צריכים זה להדפיס את הערך הנומרי של המחרוזת כדי לייצר טקסט. כאמור די טיפשי אבל מסווה מאד את מה שקורה שם. למשל נראה בקוד ש:
[𓅂++] // זה אפס, כן. נשבע לכם
וזה אומר שאם אני עושה משהו כזה:
𓊎[𓅂]
אני אקבל את התו ]. כי זה מה שיש במקום אפס במחרוזת הטקסט [object object].
כאמור מחוכם מאד וחמוד מאד. אבל מראה איך לפעמים אפשר ליצור סקריפטים שגם חוק מאד מחוכם של WAF לא היה עולה על זה. אלא אם כן יש שימוש בבינה מלאכותית, אבל כרגע הכל איטי מכדי שבינה מלאכותית תעבור על כל payload שהוא.
אז בעצם תוקף יכול בהחלט להכניס payload גם ב-WAF מאד מאד טוב. למשל משהו כזה:
`<img src="invalid_image.jpg" onerror="𓅂='',𓂀=!𓅂+𓅂,𓁄=!𓂀+𓅂,𓊎=𓅂+{},𓆣=𓂀[𓅂++],𓊝=𓂀[𓇎=𓅂],𓏢=++𓇎+𓅂,𓆗=𓊎[𓇎+𓏢],𓂀[𓆗+=𓊎[𓅂]+(𓂀.𓁄+𓊎)[𓅂]+𓁄[𓏢]+𓆣+𓊝+𓂀[𓇎]+𓆗+𓆣+𓊎[𓅂]+𓊝][𓆗](𓁄[𓅂]+𓁄[𓇎]+𓂀[𓏢]+𓊝+𓆣+'`𓅂 𓏢 𓂀 𓁄 𓆣 𓊝 𓇎`')``">`
או כמובן אחד מעשרות האלמנטים והטריקים השונים שאפשר להכניס כאלמנט HTML כזה דבר שמוזרק לתוך קוד הוא XSS שקשה להבין אותו ככזה.
אני חושב שזו דוגמה מאד טובה למה קשה מאד לחוקים סטנדרטיים למצוא payloads של XSS וסיבה טובה למה כדאי להשקיע גם ב-CSP וגם ב-Trusted types כדי למנוע דברים כאלו ולא לסמוך על פתרונות קסם. גם מתכנתי פרונט צריכים להבין מספיק באבטחת מידע. בכל מקרה, החלק עם ההירוגליפים ושאר תוים מגניבים ב-UTF8 גם ממש כדאי להכרות, אז גם אם לא השתכנעתם, אני מקווה שלפחות נהניתם מזה 🙂
6 תגובות
פעם (לפני מעל 20 שנה) javascript היה נחשב פירצת אבטחה , עד כדי כך ש IE שהגיע עם windows server 2003 לא היה מריץ javascript ברירת מחדל.
היו עוד כלי מני framework שהיה להם mode עבודה שיאפשר שעדיין האתר יעבוד גם אם javascript מבוטל בדפדפן.
מעניין אם מישהו היה אומר לפני 20 שנה ש javascript תהיה השפה הפופלארית ביותר לפיתוח (עם כוכביות) היו חושבים שהוא משוגע.
בכל מקרה , יאללה לעבור ל webassembly ולזרוק את ה javascript לפח ההיסטוריה.
חשוב – ומגניב 🙂
חבל שלא הדגשת במה מפתחים כן צריכים להתמקד – ברשימה לבנה והגנה מול השרת.
Big like!
𓅂=",𓂀=!𓅂+𓅂,𓁄=!𓂀+𓅂,𓊎=𓅂+{},𓆣=𓂀
[𓅂++],𓊝=𓂀[𓇎=𓅂],𓏢=++𓇎+𓅂,𓆗=𓊎[𓇎+𓏢
],𓂀[𓆗+=𓊎[𓅂]+(𓂀.𓁄+𓊎)[𓅂]+𓁄[𓏢]+𓆣+
𓊝+𓂀[𓇎]+𓆗+𓆣+𓊎[𓅂]+𓊝][𓆗](𓁄[𓅂]+𓁄[
𓇎]+𓂀[𓏢]+𓊝+𓆣+'`𓅂 𓏢 𓂀 𓁄 𓆣 𓊝 𓇎`')"
אפילו LARAVEL נפל בפח