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

מדיניות אבטחת תוכן (CSP) עוזרת לוודא שבעלי האתר סומכים על כל תוכן שנטען בדף. שירותי CSP מצמצמים התקפות של סקריפטים חוצי-אתרים (XSS) כי הם יכולים לחסום סקריפטים לא בטוחים שהוחדרו על ידי תוקפים. עם זאת, אם ה-CSP לא מספיק קפדני, אפשר לעקוף אותו בקלות. מידע נוסף זמין במאמר צמצום היקף הפריצות מסוג XSS (הרצת סקריפט באתר אחר) באמצעות מדיניות אבטחת תוכן (CSP) מחמירה. 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, ומספקות מעט הגנה מפני החדרת סקריפט. לעומת זאת, הגישות שמבוססות על חד-פעמיות (nonce) ועל גיבוב (hash) לא סובלות מהבעיות האלה, ומאפשרות לאמץ מדיניות מאובטחת יותר ולתחזק אותה בקלות רבה יותר.

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

CSP:

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

HTML:

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

כדי למנוע עקיפה, מדיניות CSP צריכה לאפשר לסקריפטים כל אחד להשתמש בגיבובים (hash) או בצפנים חד-פעמיים (hashed) ולהשתמש ב-'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: בדפדפנים מודרניים בגלל המשתנה החד-פעמי (nonce) ו-strict-dynamic. מידע נוסף על אימוץ CSP מחמיר זמין במדריך CSP מחמיר.

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