אירוח מאובטח של נתוני משתמשים באפליקציות אינטרנט מודרניות

David Dworken
David Dworken

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

פתרונות קלאסיים לבידוד תוכן לא מהימן

הפתרון הקלאסי להצגת תוכן בצורה מאובטחת בשליטת המשתמש הוא שימוש במה שנקרא דומיינים של ארגז חול. הרעיון הבסיסי הוא שאם הדומיין הראשי של האפליקציה הוא example.com, אפשר להציג את כל התוכן שלא מהימן ב-exampleusercontent.com. מכיוון ששני הדומיינים האלה הם חוצי אתרים, תוכן זדוני ב-exampleusercontent.com לא יכול להשפיע על example.com. אפשר להשתמש בגישה הזו כדי להציג בבטחה כל מיני תכנים לא מהימנים, כולל תמונות, הורדות ו-HTML. יכול להיות שזה לא נראה הכרחי להשתמש בזה לתמונות או להורדות, אבל זה עוזר להימנע מסיכונים שקשורים לזיהוי סוג התוכן, במיוחד בדפדפנים מדור קודם. דומיינים של ארגז חול נמצאים בשימוש נרחב בתעשייה, והם פועלים היטב כבר הרבה זמן. אבל יש להם שני חסרונות משמעותיים:

  • לעתים קרובות, אפליקציות צריכות להגביל את הגישה לתוכן למשתמש אחד, ולכן צריך להטמיע בהן אימות והרשאה. מכיוון שדומיינים של ארגז חול לא משתפים קובצי Cookie עם הדומיין הראשי של האפליקציה, קשה מאוד לעשות זאת בצורה מאובטחת. כדי לתמוך באימות, אתרים צריכים להסתמך על כתובות URL של יכולות או להגדיר קובצי Cookie נפרדים לאימות עבור דומיין ארגז החול. השיטה השנייה בעייתית במיוחד באינטרנט המודרני, שבו דפדפנים רבים מגבילים קובצי Cookie חוצי-אתרים כברירת מחדל.
  • תוכן משתמשים מבודד מהאתר הראשי, אבל לא מבודד מתוכן משתמשים אחר. כך נוצר סיכון שתוכן משתמשים זדוני יתקוף נתונים אחרים בדומיין של ארגז החול (לדוגמה, על ידי קריאת נתונים מאותו מקור).

חשוב גם לציין שדומיינים של ארגז חול עוזרים לצמצם את הסיכונים של פישינג, כי המשאבים מפולחים בבירור בדומיין מבודד.

פתרונות מודרניים להצגת תוכן משתמשים

האינטרנט התפתח עם הזמן, ועכשיו יש דרכים קלות ומאובטחות יותר להצגת תוכן לא מהימן. יש הרבה גישות שונות, ולכן נציג כאן שני פתרונות שבהם אנחנו משתמשים ב-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

מונעת את הכללת הדף באתרים אחרים

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

גישה 2: הצגת תוכן של משתמשים פעילים

אפשר גם להציג תוכן פעיל (לדוגמה, תמונות HTML או SVG) בצורה בטוחה בלי החולשות של הגישה הקלאסית של דומיין ארגז החול.

האפשרות הכי פשוטה היא להשתמש בכותרת Content-Security-Policy: sandbox כדי להנחות את הדפדפן לבודד את התגובה. לא כל דפדפני האינטרנט מטמיעים טכנולוגיות לבידוד תהליכים למסמכי ארגז חול, אבל סביר להניח ששיפורים מתמשכים במודלים של תהליכי דפדפן ישפרו את ההפרדה בין תוכן בארגז חול לבין אפליקציות להטמעה. אם התקפות SpectreJS וrenderer compromise לא נכללות במודל האיומים שלכם, סביר להניח ששימוש בארגז חול של CSP הוא פתרון מספיק. ב-Google פיתחנו פתרון שיכול לבודד באופן מלא תוכן פעיל לא מהימן, על ידי עדכון של הקונספט של דומיינים של ארגז חול. הרעיון המרכזי הוא:

  • יצירת דומיין חדש של ארגז חול שנוסף לרשימת הסיומות הציבוריות. לדוגמה, אם מוסיפים את exampleusercontent.com ל-PSL, אפשר לוודא ש-foo.exampleusercontent.com ו-bar.exampleusercontent.com הם חוצי-אתרים, ולכן מבודדים לחלוטין זה מזה.
  • כל כתובות ה-URL שתואמות ל-*.exampleusercontent.com/shim מנותבות לקובץ shim סטטי. קובץ ה-shim הזה מכיל קטע קוד קצר של HTML ו-JavaScript שמקשיב לגורם המטפל באירועים ‏message ומציג כל תוכן שהוא מקבל.
  • כדי להשתמש בזה, המוצר יוצר iframe או תיבת דו-שיח ל-$RANDOM_VALUE.exampleusercontent.com/shim ומשתמש ב-postMessage כדי לשלוח את התוכן הלא מהימן ל-shim לצורך עיבוד.
  • התוכן שעבר רינדור הופך ל-Blob ועובר רינדור בתוך iframe שבארגז חול.

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

סיכום

שני הפתרונות האלה מאפשרים לעבור מדומיינים של ארגז חול קלאסי כמו googleusercontent.com לפתרונות מאובטחים יותר שתואמים לחסימה של קובצי Cookie של צד שלישי. ב-Google כבר העברנו הרבה מוצרים לשימוש בפתרונות האלה, ויש לנו תוכניות להעברות נוספות בשנה הקרובה.