איך משתמשים ב-COOP וב-COEP כדי להגדיר את האתר כ-חסום לגישה מדומיינים אחרים

כדאי להשתמש ב-COOP וב-COEP כדי להגדיר סביבה חסומה לגישה מדומיינים אחרים ולהפעיל תכונות מתקדמות כמו SharedArrayBuffer,‏ performance.measureUserAgentSpecificMemory() וטיימר ברזולוציה גבוהה עם דיוק משופר.

פורסם: 13 באפריל 2020, עדכון אחרון: 21 ביוני 2022

במסמך הזה נסביר איך להשתמש ב-COOP וב-COEP. מידע נוסף על החשיבות של זה זמין במאמר איך להגדיר את האתר כ-cross-origin isolated באמצעות COOP ו-COEP.

חלק מ-API האינטרנט מגדילים את הסיכון למתקפות בערוץ צדדי כמו Spectre. כדי לצמצם את הסיכון הזה, דפדפנים מציעים סביבה מבודדת שנקראת 'חסום לגישה מדומיינים אחרים' (cross-origin isolated). במצב חסום לגישה מדומיינים אחרים, דף האינטרנט יוכל להשתמש בתכונות בעלות הרשאות, כולל:

API תיאור
SharedArrayBuffer נדרש עבור שרשורים של WebAssembly. האפשרות הזו זמינה החל מ-Chrome 88 ב-Android. גרסת המחשב מופעלת כברירת מחדל בעזרת בידוד אתרים, אבל היא תדרוש מצב של חסימה לגישה מדומיינים אחרים ו תושבת כברירת מחדל ב-Chrome 92.
performance.measureUserAgentSpecificMemory() התכונה זמינה מגרסה Chrome 89.
performance.now(), performance.timeOrigin זמין בדפדפנים רבים, עם רזולוציה מוגבלת של 100 מיקרו-שניות ומעלה. בבידוד בין מקורות שונים, הרזולוציה יכולה להיות 5 מיקרו-שניות ומעלה.
תכונות שיהיו זמינות במצב 'חסום לגישה מדומיינים אחרים'.

המצב 'חסום לגישה מדומיינים אחרים' מונע גם שינויים ב-document.domain. (האפשרות לשנות את document.domain מאפשרת תקשורת בין מסמכים מאותו האתר, ונחשבת לפרצה במדיניות המקור הזהה).

כדי להביע הסכמה למצב של חסום לגישה מדומיינים אחרים, צריך לשלוח את כותרות ה-HTTP הבאות במסמך הראשי:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

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

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

מילון מונחים

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

איך להגדיר את האתר כך שיהיה חסום לגישה מדומיינים אחרים

1. הגדרה של Cross-Origin-Opener-Policy: same-origin במסמך ברמה העליונה

אם מפעילים את COOP: same-origin במסמך ברמה העליונה, חלונות עם אותו מקור וחלונות שנפתחו מהמסמך יהיו בקבוצת הקשרים נפרדת של גלישה, אלא אם הם באותו מקור עם אותה הגדרת COOP. לכן, הבידוד נאכף בחלונות שנפתחים והתקשורת ההדדית בין שני החלונות מושבתת.

קבוצת הקשרים של הגלישה היא קבוצה של חלונות שיכולים להפנות אחד לשני. לדוגמה, מסמך ברמה העליונה ומסמכי הצאצא שלו שמוטמעים באמצעות <iframe>. אם אתר (https://a.example) פותח חלון דו-שיח (https://b.example), חלון הפתיחה וחלון הדו-שיח חולקים את אותו הקשר גלישה, ולכן יש להם גישה זה לזה באמצעות ממשקי DOM API כמו window.opener.

איור שמייצג קבוצת תוכן של גלישה, עם משתמש שמקיים אינטראקציה עם רכיבי הדף.

אפשר לבדוק אם החלון שפותח והחלון שנפתח נמצאים בקבוצות נפרדות של הקשרים לגלישה מתוך כלי הפיתוח.

2. הפעלת CORP או CORS במשאבים

מוודאים שכל המשאבים בדף נטענים עם כותרות HTTP של CORP או CORS. השלב הזה נדרש כדי לבצע את שלב ארבע, הפעלת COEP.

אלה הפעולות שצריך לבצע, בהתאם לאופי המשאב:

  • אם המשאב אמור להיטען רק מאותו מקור, צריך להגדיר את הכותרת Cross-Origin-Resource-Policy: same-origin.
  • אם המשאב אמור להיטען רק מאותו אתר אבל ממקורות שונים, צריך להגדיר את הכותרת Cross-Origin-Resource-Policy: same-site.
  • אם המשאב נטען ממקורות חוצי-דומיין שנמצאים בשליטתכם, כדאי להגדיר את הכותרת Cross-Origin-Resource-Policy: cross-origin.
  • למשאבים ממקורות שונים שאין לכם שליטה עליהם:
    • אם המשאב מוגש עם CORS, צריך להשתמש במאפיין crossorigin בתג ה-HTML של הטעינה. (לדוגמה, <img src="***" crossorigin>).
    • צריך לבקש מבעלי המשאב לתמוך ב-CORS או ב-CORP.
  • במקרה של iframe, פועלים לפי אותם עקרונות ומגדירים את התג Cross-Origin-Resource-Policy: cross-origin (או same-site, same-origin בהתאם להקשר).
  • סקריפטים שנטענים באמצעות WebWorker צריכים להיות מוגשים מאותו מקור, כך שלא צריך כותרות CORP או CORS.
  • כדי להטמיע מסמך או worker שמוגשים עם COEP: require-corp, צריך להגדיר את הכותרת Cross-Origin-Resource-Policy: cross-origin במשאבי משנה ממקורות שונים שנטענים בלי CORS. לדוגמה, זה חל על <script>, importScripts, <link>, <video>, <iframe> וכו'.

בידוד ב-iframes

כדי להפעיל בידוד ממקורות שונים במסמך שמוטמע ב-iframe, צריך להחיל את מדיניות ההרשאות של allow="cross-origin-isolated" על התג <iframe> ולעמוד בתנאים הבאים. גם כל השרשרת של המסמכים, כולל מסגרות אב ומסגרות צאצא, צריכה להיות חסומה לגישה מדומיינים אחרים, גם כן.

3. שימוש בכותרת ה-HTTP ‏COEP Report-Only להערכת משאבים מוטמעים

לפני שמפעילים את COEP באופן מלא, אפשר להריץ בדיקה יבשה באמצעות הכותרת Cross-Origin-Embedder-Policy-Report-Only כדי לבדוק אם המדיניות פועלת בפועל. תקבלו דוחות בלי לחסום תוכן מוטמע.

החלת ההגדרה הזו באופן רקורסיבי על כל המסמכים, כולל המסמך ברמה העליונה, ה-iframe וסקריפטים של worker. מידע על כותרת HTTP מסוג Report-Only זמין במאמר מעקב אחרי בעיות באמצעות Reporting API.

4. הפעלת COEP

אפשר לבצע את השלב הזה רק אחרי שמוודאים שהמשאבים כוללים הפעלה של CORP או CORS.

אחרי שמוודאים שהכול פועל ושאפשר לטעון את כל המשאבים בהצלחה, מחליפים את הכותרת Cross-Origin-Embedder-Policy-Report-Only בכותרת Cross-Origin-Embedder-Policy עם אותו ערך בכל המסמכים, כולל אלה שמוטמעים באמצעות תגי iframe וסקריפטים של worker.

קביעה אם הבידוד הצליח

המאפיין self.crossOriginIsolated מחזיר true כשדף האינטרנט נמצא במצב חסום לגישה מדומיינים אחרים, וכל המשאבים והחלונות מבודדים באותה קבוצת הקשרים לגלישה. אתם יכולים להשתמש בממשק ה-API הזה כדי לקבוע אם הצלחתם לבודד את קבוצת הקשרים של הגלישה ולקבל גישה לתכונות כמו performance.measureUserAgentSpecificMemory().

לנפות באגים

יכול להיות שתיתקלו בבעיות ב-COOP וב-COEP. אפשר להשתמש בכלים למפתחים בדפדפן או ב-Reporting API כדי לבצע ניפוי באגים.

ניפוי באגים באמצעות כלי הפיתוח ל-Chrome

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

אם יש בעיה ב-COEP, יופיע (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep) בעמודה סטטוס.

בעיות ב-COEP בעמודה 'סטטוס' בחלונית 'רשת'.

אחר כך אפשר ללחוץ על הרשומה כדי לראות פרטים נוספים.

פרטים על בעיית ה-COEP מוצגים בכרטיסייה Headers (כותרות) אחרי שלוחצים על משאב רשת בחלונית &quot;רשת&quot;.

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

אפשר לבדוק את הסטטוס של ה-iframe, כמו הזמינות של SharedArrayBuffer וכו'.

כלי לבדיקת iframe בכלי הפיתוח ל-Chrome.

אפשר גם לבדוק את הסטטוס של חלונות הדו-שיח, למשל אם הם מבודדים ממקורות שונים.

חלון דו-שיח של כלי הפיתוח ל-Chrome עם כלי לבדיקת רכיבים

זיהוי בעיות באמצעות Reporting API

Reporting API הוא מנגנון נוסף שבאמצעותו אפשר לזהות בעיות שונות. אתם יכולים להגדיר את Reporting API כך שהדפדפן של המשתמשים ישלח דוח בכל פעם ש-COEP חוסם טעינה של משאב או ש-COOP מבודד חלון דו-שיח. דפדפן Chrome תומך ב-Reporting API מגרסה 69 ואילך, למגוון שימושים כולל COEP ו-COOP.

איך מגדירים את Reporting API ומגדירים שרת לקבלת דוחות

דוגמה לדוח COEP

דוגמה למטען ייעודי (payload) של דוח COEP כשמשאב בין מקורות נחסם:

[{
  "age": 25101,
  "body": {
    "blocked-url": "https://third-party-test.glitch.me/check.svg?",
    "blockedURL": "https://third-party-test.glitch.me/check.svg?",
    "destination": "image",
    "disposition": "enforce",
    "type": "corp"
  },
  "type": "coep",
  "url": "https://cross-origin-isolation.glitch.me/?coep=require-corp&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4249.0 Safari/537.36"
}]

דוח COOP לדוגמה

דוגמה למטען ייעודי (payload) של דוח COOP כשתיבת דו-שיח נפתחת בבידוד:

[{
  "age": 7,
  "body": {
    "disposition": "enforce",
    "effectivePolicy": "same-origin",
    "nextResponseURL": "https://third-party-test.glitch.me/popup?report-only&coop=same-origin&",
    "type": "navigation-from-response"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

כשקבוצות שונות של הקשרים לגלישה מנסות לגשת זו לזו (רק במצב report-only), ‏ COOP שולח גם דוח. לדוגמה, דוח שנוצר כשמנסים להשתמש ב-postMessage() ייראה כך:

[{
  "age": 51785,
  "body": {
    "columnNumber": 18,
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "lineNumber": 83,
    "property": "postMessage",
    "sourceFile": "https://cross-origin-isolation.glitch.me/popup.js",
    "type": "access-from-coop-page-to-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
},
{
  "age": 51785,
  "body": {
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "property": "postMessage",
    "type": "access-to-coop-page-from-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

חטיפות דסקית

כדי להגדיר דף אינטרנט למצב מיוחד של חסימה לגישה מדומיינים אחרים, צריך להשתמש בשילוב של כותרות HTTP מסוג COOP ו-COEP. אתם יכולים לבדוק את self.crossOriginIsolated כדי לדעת אם דף אינטרנט נמצא במצב חסום לגישה מדומיינים אחרים.

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

משאבים

עדכונים במסמכים

  • 21 ביוני 2022: גם סקריפטים של Worker צריכים טיפול כשמפעילים בידוד בין מקורות שונים. הוספתי כמה הסברים.
  • 5 באוגוסט 2021: JS Self-Profiling API הוזכר כאחד מממשקי ה-API שנדרשת עבורם בידוד בין מקורות שונים, אבל בעקבות שינוי שחל לאחרונה בכיוון, הוא הוסר.
  • 6 במאי 2021: על סמך המשוב והבעיות שדווחו, החלטנו לשנות את ציר הזמן של SharedArrayBufferהשימוש באתרים שלא חסומים לגישה מדומיינים אחרים כך שהשימוש יוגבל ב-Chrome M92.
  • ‫16 באפריל 2021: הוספנו הערות לגבי מצב COEP ללא אישורים ו-COOP same-origin-allow-popups כתנאי מקל לבידוד בין מקורות שונים.
  • 5 במרץ 2021: הסרנו את המגבלות על SharedArrayBuffer,‏ performance.measureUserAgentSpecificMemory() ופונקציות ניפוי הבאגים, שמופעלות עכשיו באופן מלא ב-Chrome 89. הוספנו יכולות חדשות, performance.now() וperformance.timeOrigin, שיהיו מדויקות יותר.
  • 19 בפברואר 2021: הוספנו הערה לגבי מדיניות התכונות allow="cross-origin-isolated" ופונקציונליות ניפוי הבאגים בכלי הפיתוח.
  • 15 באוקטובר 2020: self.crossOriginIsolated זמין מגרסה Chrome 87. בהתאם לכך, document.domain הוא קבוע כש-self.crossOriginIsolated מחזירה true. ‫performance.measureUserAgentSpecificMemory() מסיימת את גרסת המקור לניסיון שלה, ומופעלת כברירת מחדל ב-Chrome 89. התכונה Shared Array Buffer ב-Android Chrome תהיה זמינה החל מגרסה Chrome 88.