אפליקציות אינטרנט רבות צריכות להציג תוכן שנמצא בשליטת המשתמש. זה יכול להיות פשוט כמו הצגת תמונות שהועלו על ידי משתמשים (לדוגמה, תמונות פרופיל), או מורכב כמו עיבוד HTML בשליטת המשתמש (לדוגמה, מדריך לפיתוח אתרים). מאז ומתמיד היה קשה לבצע זאת בצורה מאובטחת, לכן עבדנו כדי למצוא פתרונות קלים אך מאובטחים שאפשר להחיל על רוב הסוגים של אפליקציות אינטרנט.
פתרונות קלאסיים לבידוד של תוכן לא מהימן
הפתרון הקלאסי להצגה מאובטחת של תוכן שנמצא בשליטת המשתמשים הוא להשתמש בדומיינים של ארגז חול. הרעיון הבסיסי הוא שאם הדומיין הראשי של האפליקציה הוא example.com
, אפשר להציג את כל התוכן הלא מהימן ב-exampleusercontent.com
. מכיוון ששני הדומיינים האלה הם אתרים שונים, תוכן זדוני ב-exampleusercontent.com
לא יכול להשפיע על example.com
.
אפשר להשתמש בגישה הזו כדי להציג באופן בטוח כל מיני סוגים של תוכן לא מהימן, כולל תמונות, הורדות ו-HTML. לא נראה שצריך להשתמש בתכונה הזו לצורך תמונות או הורדות, אבל הפעולה הזו מונעת סיכונים שנובעים מהחיפוש של תוכן, במיוחד בדפדפנים מדור קודם.
דומיינים של ארגז חול (Sandbox) נמצאים בשימוש נרחב בתחום, והם פועלים היטב במשך זמן רב. אבל יש להן שני חסרונות עיקריים:
- לעתים קרובות יישומים צריכים להגביל את הגישה לתוכן למשתמש יחיד. לשם כך נדרשים הטמעת אימות והרשאה. מאחר שדומיינים של Sandbox לא משתפים בכוונה קובצי cookie עם הדומיין הראשי של היישום, קשה מאוד לעשות זאת באופן מאובטח. כדי לתמוך באימות, אתרים צריכים להסתמך על כתובות URL עם יכולות או להגדיר קובצי cookie נפרדים לאימות לדומיין ה-Sandbox. השיטה השנייה הזו בעייתית במיוחד באינטרנט המודרני, שבו דפדפנים רבים מגבילים קובצי cookie בין אתרים כברירת מחדל.
- תוכן המשתמשים מבודד מהאתר הראשי, אבל הוא לא מבודד מתוכן של משתמשים אחרים. הפעולה הזו יוצרת את הסיכון לכך שתוכן זדוני של משתמשים יתקוף נתונים אחרים בדומיין של Sandbox (לדוגמה, על ידי קריאה של נתונים מאותו מקור).
חשוב גם לציין שדומיינים של Sandbox עוזרים לצמצם את סיכוני הפישינג, מאחר שהמשאבים פרוסים באופן ברור בדומיין מבודד.
פתרונות מודרניים להצגת תוכן של משתמשים
עם הזמן האינטרנט התפתח, ויש דרכים קלות ומאובטחות יותר להציג תוכן שאינו מהימן. יש כאן גישות רבות, ולכן מתוארות שני פתרונות שנמצאים כרגע בשימוש נרחב ב-Google.
גישה 1: הצגת תוכן לא פעיל של משתמשים
אם אתר צריך להציג רק תוכן לא פעיל של משתמשים (כלומר תוכן שאינו HTML או JavaScript, למשל תמונות והורדות), כעת ניתן לעשות זאת בבטחה ללא דומיין ארגז חול מבודד. יש שני שלבים עיקריים:
- תמיד להגדיר את הכותרת
Content-Type
לסוג MIME ידוע שנתמך על ידי כל הדפדפנים ומבטיח שלא תכיל תוכן פעיל (אם יש ספק, האפשרותapplication/octet-stream
היא הבחירה הבטוחה). - בנוסף, חשוב להגדיר תמיד את כותרות התגובות הבאות כדי להבטיח שהדפדפן יבודד את התגובה במלואה.
כותרת תגובה | מטרה |
---|---|
X-Content-Type-Options: nosniff |
מניעת צנזור תוכן |
Content-Disposition: attachment; filename="download" |
מפעיל הורדה במקום רינדור |
Content-Security-Policy: sandbox |
ארגז חול של התוכן כאילו הוא הוצג בדומיין נפרד |
Content-Security-Policy: default-src ‘none' |
ההגדרה משביתה את ההפעלה של JavaScript (וההכללה של משאבי משנה) |
Cross-Origin-Resource-Policy: same-site |
מניעת הכללה של הדף בין אתרים |
השילוב של הכותרות הזה מבטיח שהתגובה תיטען כמשאב משנה רק על ידי האפליקציה שלכם, או שתוריד את התגובה כקובץ על ידי המשתמש. בנוסף, הכותרות מספקות כמה שכבות הגנה מפני באגים בדפדפן דרך כותרת ה-Sandbox של CSP וההגבלה default-src
. באופן כללי, ההגדרה שפורטה למעלה מספקת ביטחון גבוה שהתגובות שמוצגות כך לא יכולות להוביל לנקודות חולשה של הזרקה או בידוד.
מבט מעמיק על ההגנה
למרות שהפתרון שלמעלה מייצג הגנה מספקת מפני XSS, יש מספר אמצעי הקשחה נוספים שתוכלו ליישם כדי לספק שכבות אבטחה נוספות:
- צריך להגדיר את הכותרת
X-Content-Security-Policy: sandbox
לתאימות עם IE11. - צריך להגדיר את הכותרת
Content-Security-Policy: frame-ancestors 'none'
כדי לחסום את ההטמעה של נקודת הקצה. - תוכן של משתמשי Sandbox בתת-דומיין מבודד על ידי:
- הצגת תוכן של משתמשים בתת-דומיין מבודד (למשל, Google משתמשת בדומיינים כגון
product.usercontent.google.com
). - צריך להגדיר את
Cross-Origin-Opener-Policy: same-origin
ואתCross-Origin-Embedder-Policy: require-corp
כדי להפעיל בידוד בין מקורות.
- הצגת תוכן של משתמשים בתת-דומיין מבודד (למשל, Google משתמשת בדומיינים כגון
גישה שנייה: הצגת תוכן פעיל של משתמשים
ניתן להציג באופן בטוח תוכן פעיל (לדוגמה, תמונות HTML או SVG) גם ללא נקודות החולשה של גישת הדומיין הקלאסית של Sandbox.
האפשרות הפשוטה ביותר היא לנצל את הכותרת Content-Security-Policy: sandbox
כדי להורות לדפדפן לבודד את התגובה. לא כל דפדפני האינטרנט מטמיעים כרגע בידוד של תהליך עבור מסמכי ארגז חול, אבל חידודים מתמשכים במודלים של עיבוד דפדפן צפויים לשפר את ההפרדה בין תוכן שנמצא בארגז חול לבין הטמעת אפליקציות. אם התקפות SpectreJS ופריצה של renderer הן מחוץ למודל האיום, השימוש ב-Sandbox של CSP הוא כנראה פתרון מספק.
ב-Google פיתחנו פתרון שיכול לבודד באופן מלא תוכן פעיל לא מהימן על ידי מודרניזציה של המושג 'דומיינים של ארגז חול' (Sandbox). הרעיון המרכזי הוא:
- יוצרים דומיין Sandbox חדש שיתווסף לרשימת הסיומות הציבוריות. לדוגמה, אם מוסיפים
exampleusercontent.com
ל-PSL, אפשר להבטיח ש-foo.exampleusercontent.com
ו-bar.exampleusercontent.com
נמצאים באתרים שונים ומבודדים באופן מלא זה מזה. - כתובות URL שתואמות ל-
*.exampleusercontent.com/shim
ינותבו לקובץ shim סטטי. קובץ shim מכיל קטע קוד קצר של HTML ו-JavaScript. הוא מאזין ל-handler של האירועים שלmessage
ומעבד כל תוכן שהוא מקבל. - כדי להשתמש בתכונה הזו, המוצר יוצר iframe או חלון קופץ אל
$RANDOM_VALUE.exampleusercontent.com/shim
, ומשתמש ב-postMessage
כדי לשלוח את התוכן הלא מהימן ל-shim לצורך רינדור. - התוכן שעבר רינדור הופך ל-Blob ומעובד ב-iframe שבארגז חול (sandbox).
בהשוואה לגישה הקלאסית של דומיינים של Sandbox, השיטה הזו מבטיחה שכל התוכן מבודד לגמרי באתר ייחודי. בנוסף, מכיוון שהאפליקציה הראשית מטפלת באחזור הנתונים המיועדים לעיבוד, כבר אין צורך להשתמש בכתובות URL של יכולות.
סיכום
יחד, שני הפתרונות האלה מאפשרים לעבור מדומיינים קלאסיים של Sandbox, כמו googleusercontent.com
, לפתרונות מאובטחים יותר שתואמים לחסימת קובצי cookie של צד שלישי. ב-Google כבר העברנו מוצרים רבים לשימוש בפתרונות האלה, ואנחנו מתכננים לבצע עוד העברות לשנה הבאה.