איך לוודא שמדיניות CSP יעילה נגד מתקפות XSS

Content Security Policy (CSP) עוזר לוודא שכל תוכן שנטען בדף מהימן על ידי בעלי האתר. שירותי CSP מצמצמים התקפות של סקריפטים חוצי-אתרים (XSS) כי הם יכולים לחסום סקריפטים לא בטוחים שהוחדרו על ידי תוקפים. עם זאת, אפשר לעקוף את ה-CSP בקלות אם הוא לא מחמיר מספיק. מידע נוסף זמין במאמר צמצום השימוש בסקריפטים חוצי-אתרים (XSS) באמצעות מדיניות מחמירה של Content Security Policy. מערכת Lighthouse אוספת נתוני CSP שנאכפים במסמך הראשי, ומדווחת על בעיות מ-CSP Evaluator אם אפשר לעקוף אותן.

בדוח Lighthouse מוצגת אזהרה שלא נמצאה מדיניות CSP במצב אכיפה.
בדוח Lighthouse מוצגת אזהרה שלא נמצאה מדיניות CSP במצב אכיפה.

שיטות העבודה הנדרשות בשביל מדיניות CSP שלא ניתנת לעקיפה

חשוב ליישם את השיטות הבאות כדי להבטיח שלא תהיה אפשרות לעקוף את מדיניות ה-CSP. אם אפשר לעקוף את מדיניות ה-CSP, תוצג ב-Lighthouse אזהרה על רמת חומרה גבוהה.

יעדי CSP XSS

כדי לטרגט ל-XSS, מדיניות CSP צריכה לכלול את ההוראות script-src, object-src ו-base-uri. גם ב-CSP אין שגיאות תחביר.

script-src ו-object-src מאבטחים את הדף מפני סקריפטים לא בטוחים ויישומי פלאגין לא בטוחים, בהתאמה. לחלופין, ניתן להשתמש ב-default-src כדי להגדיר מדיניות רחבה במקום הוראות רבות כולל script-src ו-object-src.

המדיניות base-uri מונעת החדרת תגי <base> לא מורשים, שיכולים לשמש להפניה אוטומטית של כל כתובות ה-URL היחסיות (כמו סקריפטים) לדומיין שנשלט על ידי תוקף.

מדיניות CSP משתמשת בגיבובים (hash) או בצפנים חד-פעמיים כדי למנוע עקיפה של רשימת ההיתרים

מדיניות CSP שמגדירה רשימת היתרים של script-src מסתמך על ההנחה שכל התשובות שמגיעות מדומיין מהימן הן בטוחות, ואפשר להריץ אותן כסקריפטים. עם זאת, ההנחה הזו לא רלוונטית לאפליקציות מודרניות; דפוסים נפוצים מסוימים כמו חשיפת ממשקי JSONP ואירוח עותקים של ספריית AngularJS מאפשרים לתוקפים לצאת מגבולות CSP.

בפועל, גם אם זה לא ברור למחברי האפליקציות, ניתן לעקוף את רוב script-srcרשימות ההיתרים על ידי תוקף באג XSS, ומספקות מעט הגנה מפני החדרת סקריפט. לעומת זאת, גישות שמבוססות על חד-פעמים ומבוססות על גיבוב לא סובלות מהבעיות האלה, ומאפשרות להשתמש במדיניות מאובטחת יותר ולשמור עליה.

לדוגמה, הקוד הזה משתמש בנקודת קצה מסוג JSONP שמתארחת בדומיין מהימן כדי להחדיר סקריפט שנשלט על ידי תוקף:

CSP:

script-src https://trusted.example.com

HTML:

<script src="https://trusted.example.com/path/jsonp?callback=alert(document.domain)//"></script>

כדי למנוע עקיפה, מדיניות CSP צריכה לאפשר לסקריפטים כל אחד להשתמש בגיבובים (hash) או בצפנים חד-פעמיים, ולהשתמש ב-'strict- dynamic'. במקום להוסיף לרשימת היתרים.

המלצות נוספות ל-CSP מאובטח

כדאי ליישם את השיטות הבאות כדי לשפר את האבטחה והתאימות. אם ה-CSP לא תעבוד בהתאם לאחת מההמלצות, תוצג ב-Lighthouse אזהרה על רמת חומרה בינונית.

הגדרת דיווח על CSP

הגדרה של יעד לדיווח תעזור לכם לעקוב אחרי תקלות. אפשר להגדיר את יעד הדיווח באמצעות ההוראות report-uri או report-to. report-to לא נתמך כרגע בכל הדפדפנים המתקדמים, לכן מומלץ להשתמש בשניהם או רק ב-report-uri.

אם יש תוכן שמפר את מדיניות ה-CSP, הדפדפן ישלח דוח ליעד שהוגדר. צריך לוודא שהגדרת אפליקציה ביעד הזה שמטפלת בדוחות האלה.

הגדרת ה-CSP בכותרת HTTP

אפשר להגדיר CSP במטא תג באופן הבא:

<meta http-equiv="Content-Security-Policy" content="script-src 'none'">

עם זאת, אם אפשר, מומלץ להגדיר CSP בכותרת תגובה של HTTP. הזרקה לפני המטא תג תעקוף את ה-CSP. בנוסף, אין תמיכה ב-frame-ancestors, ב-sandbox ובדיווח ב-CSP של מטא תגים.

צריך לוודא שמדיניות CSP תואמת לאחור

לא כל הדפדפנים תומכים בגיבובים או בצפנים חד-פעמיים של CSP, ולכן מומלץ להוסיף את unsafe-inline כחלופה לדפדפנים שלא עומדים בדרישות. אם הדפדפן תומך בגיבובים/צפנים חד-פעמיים, המערכת תתעלם מ-unsafe-inline.

באופן דומה, strict-dynamic לא נתמך בכל הדפדפנים. מומלץ להגדיר רשימת היתרים כחלופה לכל דפדפן שלא עומד בדרישות. המערכת תתעלם מרשימת ההיתרים בדפדפנים שתומכים ב-strict-dynamic.

איך לפתח מדיניות CSP מחמירה

למטה תוכלו לראות דוגמה לשימוש במדיניות CSP מחמירה עם מדיניות שלא מבוססת על צופן חד-פעמי (nonce).

CSP:

script-src 'nonce-random123' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none';
base-uri 'none';
report-uri https://reporting.example.com;

HTML:

<script nonce="random123" src="https://trusted.example.com/trusted_script.js"></script>

random123 הוא כל מחרוזת Base64 שנוצרת בצד השרת בכל פעם שהדף נטען. בדפדפנים מודרניים, המערכת מתעלמת מ-unsafe-inline ומ-https: בגלל צפנים חד-פעמיים ו-strict-dynamic. מידע נוסף על הטמעה של מדיניות CSP מחמירה זמין במדריך Strict CSP.

אפשר לבדוק ב-CSP אם יש עקיפה אפשרית באמצעות Lighthouse ומעריך CSP. אם רוצים לבדוק מדיניות CSP חדשה בלי הסיכון לשיבושים בדפים קיימים, צריך להגדיר את ה-CSP במצב דוח בלבד ולהשתמש ב-Content-Security-Policy-Report-Only בתור שם הכותרת. הפעולה הזו תשלח הפרות של מדיניות CSP לכל יעדי הדיווח שהגדרתם עם report-to ועם report-uri, אבל היא לא תאכוף את מדיניות ה-CSP בפועל.