כאן מוסבר למה צריך חסימה לגישה מדומיינים אחרים כדי להשתמש בתכונות מתקדמות כמו SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
וטיימר ברזולוציה גבוהה עם דיוק משופר.
מבוא
במאמר הפיכת האתר ל'מבודד ממקורות שונים' באמצעות COOP ו-COEP הסברנו איך להגדיר את האתר למצב 'מבודד ממקורות שונים' באמצעות COOP ו-COEP. זהו מאמר משלים שמסביר למה צריך לחסום את הגישה מדומיינים אחרים כדי להפעיל תכונות מתקדמות בדפדפן.
רקע
האינטרנט מבוסס על מדיניות המקור הזהה: תכונת אבטחה שמגבילה את האופן שבו מסמכים וסקריפטים יכולים ליצור אינטראקציה עם משאבים ממקור אחר. העיקרון הזה מגביל את הדרכים שבהן אתרים יכולים לגשת למשאבים ממקורות שונים. לדוגמה, מסמך מ-https://a.example
לא יכול לגשת לנתונים שמארחים ב-https://b.example
.
עם זאת, היו כמה חריגים היסטוריים למדיניות המקור הזהה. כל אתר יכול:
- הטמעת iframes ממקורות שונים
- לכלול משאבים חוצי-מקורות כמו תמונות או סקריפטים
- פתיחת חלונות קופצים ממקורות שונים עם הפניה ל-DOM
אם היה אפשר לעצב את האינטרנט מחדש, החריגים האלה לא היו קיימים. לצערנו, עד שהקהילה האינטרנטית הבינה את היתרונות המרכזיים של מדיניות קפדנית של אותו מקור, האינטרנט כבר הסתמך על החריגים האלה.
הבאגים שקשורים לאבטחה כתוצאה ממדיניות המקור הזהה המקלה תוקנו בשתי דרכים. אחת הדרכים הייתה באמצעות הצגת פרוטוקול חדש שנקרא שיתוף משאבים בין מקורות (CORS). המטרה של הפרוטוקול הזה היא לוודא שהשרת מאפשר שיתוף משאב עם מקור נתון. דרך נוספת היא להסיר באופן מרומז את הגישה הישירה של הסקריפט למשאבים ממקורות שונים, תוך שמירה על תאימות לאחור. משאבים כאלה ממקורות שונים נקראים משאבים 'אטומים'. לדוגמה, זו הסיבה לכך ששינוי הפיקסלים של תמונה ממקור אחר באמצעות CanvasRenderingContext2D
נכשל, אלא אם מוחל על התמונה CORS.
כל ההחלטות האלה בנושא מדיניות מתקבלות בתוך קבוצה של הקשרים של גלישה.
במשך זמן רב, השילוב של CORS ומשאבים אטומים הספיק כדי להפוך את הדפדפנים לבטוחים. לפעמים התגלו מקרים חריגים (כמו פגיעויות ב-JSON) שדרשו תיקון, אבל באופן כללי, העיקרון של אי-מתן גישת קריאה ישירה לבייטים הגולמיים של משאבים ממקורות שונים הצליח.
הכול השתנה עם Spectre, שמאפשר לקרוא נתונים שנטענים לאותה קבוצת הקשר גלישה כמו הקוד שלכם. על ידי מדידת הזמן שלוקח לפעולות מסוימות, התוקפים יכולים לנחש את התוכן של מטמון המעבד, וכך גם את התוכן של זיכרון התהליך. מתקפות כאלה של תזמון אפשריות באמצעות טיימרים עם רמת פירוט נמוכה שקיימים בפלטפורמה, אבל אפשר להאיץ אותן באמצעות טיימרים עם רמת פירוט גבוהה, גם טיימרים מפורשים (כמו performance.now()
) וגם טיימרים מרומזים (כמו SharedArrayBuffer
s). אם evil.com
מטמיע תמונה ממקורות שונים, הוא יכול להשתמש בהתקפת Spectre כדי לקרוא את נתוני הפיקסלים שלה, מה שהופך את אמצעי ההגנה שמסתמכים על 'אטימות' ללא יעילים.
באופן אידיאלי, השרת שבבעלותו המשאב צריך לבדוק באופן מפורש את כל הבקשות חוצות המקורות. אם הנתונים לא עוברים בדיקה בשרת שאליו שייך המשאב, הם לא יגיעו לקבוצת ההקשרים של הגלישה של גורם זדוני, ולכן לא יהיו נגישים להתקפות Spectre שדף אינטרנט יכול לבצע. המצב הזה נקרא 'מבודד ממקורות שונים'. בדיוק בשביל זה נוצרו COOP ו-COEP.
במצב מבודד בין מקורות, האתר ששולח את הבקשה נחשב לפחות מסוכן, והדבר מאפשר שימוש בתכונות מתקדמות כמו SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
וטיימרים ברזולוציה גבוהה עם דיוק טוב יותר, שאחרת עלולים לשמש להתקפות כמו Spectre. היא גם מונעת שינוי של document.domain
.
מדיניות הטמעה ממקורות שונים
מדיניות הטמעה ממקורות שונים (COEP) מונעת טעינה של משאבים ממקורות שונים במסמך שלא הוענקה להם הרשאה מפורשת (באמצעות CORP או CORS). באמצעות התכונה הזו, אפשר להצהיר שמסמך לא יכול לטעון משאבים כאלה.
כדי להפעיל את המדיניות הזו, מוסיפים את כותרת ה-HTTP הבאה למסמך:
Cross-Origin-Embedder-Policy: require-corp
הערך היחיד שניתן להשתמש בו ב-COEP הוא require-corp
. ההגדרה הזו אוכפת את המדיניות שלפיה המסמך יכול לטעון רק משאבים מאותו מקור, או משאבים שמסומנים במפורש כמשאבים שאפשר לטעון ממקור אחר.
כדי שיהיה אפשר לטעון משאבים ממקור אחר, הם צריכים לתמוך בשיתוף משאבים בין מקורות (CORS) או במדיניות משאבים בין מקורות (CORP).
שיתוף משאבים בין מקורות
אם משאב ממקור אחר תומך בשיתוף משאבים בין מקורות (CORS), אפשר להשתמש במאפיין crossorigin
כדי לטעון אותו לדף האינטרנט בלי ש-COEP יחסום אותו.
<img src="https://third-party.example.com/image.jpg" crossorigin>
לדוגמה, אם משאב התמונה הזה מוגש עם כותרות CORS, צריך להשתמש במאפיין crossorigin
כדי שבקשת האחזור של המשאב תשתמש במצב CORS. בנוסף, הפעולה הזו מונעת את טעינת התמונה אלא אם מוגדרות כותרות CORS.
באופן דומה, אפשר לשלוף נתונים ממקורות שונים באמצעות השיטה fetch()
, שלא דורשת טיפול מיוחד כל עוד השרת מגיב עם כותרות ה-HTTP הנכונות.
מדיניות משאבים ממקורות שונים
מדיניות שיתוף משאבים בין מקורות (CORP) הושקה במקור כאפשרות בחירה כדי להגן על המשאבים שלכם מפני טעינה על ידי מקור אחר. במסגרת COEP, CORP יכולה לציין את המדיניות של בעל המשאב לגבי מי יכול לטעון משאב.
הכותרת Cross-Origin-Resource-Policy
יכולה לקבל שלושה ערכים אפשריים:
Cross-Origin-Resource-Policy: same-site
אפשר לטעון משאבים שמסומנים ב-same-site
רק מאותו אתר.
Cross-Origin-Resource-Policy: same-origin
אפשר לטעון משאבים שמסומנים ב-same-origin
רק מאותו מקור.
Cross-Origin-Resource-Policy: cross-origin
כל אתר יכול לטעון משאבים שמסומנים בסימן cross-origin
. (הערך הזה נוסף למפרט CORP יחד עם COEP).
מדיניות פותחן מרובת מקורות
מדיניות של פתיחה ממקורות שונים (COOP) מאפשרת לוודא שחלון ברמה העליונה מבודד ממסמכים אחרים על ידי הצבתם בקבוצת הקשרים שונה של גלישה, כך שהם לא יכולים ליצור אינטראקציה ישירה עם החלון ברמה העליונה. לדוגמה, אם מסמך עם COOP פותח חלון קופץ, המאפיין window.opener
שלו יהיה null
. בנוסף, המאפיין .closed
של ההפניה של חלון הפתיחה אליו יחזיר את הערך true
.
הכותרת Cross-Origin-Opener-Policy
יכולה לקבל שלושה ערכים אפשריים:
Cross-Origin-Opener-Policy: same-origin
מסמכים שמסומנים בתווית same-origin
יכולים לחלוק את אותה קבוצת הקשר גלישה עם מסמכים מאותו מקור שגם הם מסומנים בתווית same-origin
.
Cross-Origin-Opener-Policy: same-origin-allow-popups
מסמך ברמה העליונה עם same-origin-allow-popups
שומר הפניות לכל החלונות הקופצים שלו שלא מוגדרת להם מדיניות COOP או שהם לא נכללים בבידוד כי מוגדרת להם מדיניות COOP של unsafe-none
.
Cross-Origin-Opener-Policy: unsafe-none
unsafe-none
היא ברירת המחדל ומאפשרת להוסיף את המסמך לקבוצת הקשר של הדפדפן של החלון הקופץ, אלא אם לחלון הקופץ עצמו יש COOP של same-origin
.
סיכום
אם רוצים לקבל גישה מובטחת לתכונות מתקדמות כמו SharedArrayBuffer
,
performance.measureUserAgentSpecificMemory()
או טיימרים ברזולוציה גבוהה עם דיוק משופר, צריך לזכור שהמסמך צריך להשתמש גם ב-COEP עם הערך require-corp
וגם ב-COOP עם הערך same-origin
. אם אף אחת מהן לא קיימת, הדפדפן לא יבטיח בידוד מספיק כדי להפעיל את התכונות המתקדמות האלה בצורה בטוחה. כדי לדעת מה המצב של הדף, בודקים אם הפקודה self.crossOriginIsolated
מחזירה את הערך true
.
כאן מוסבר איך להטמיע את התכונה הזו באתר באמצעות COOP ו-COEP.