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

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

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

במאמר הזה מוסבר איך להשתמש ב-COOP וב-COEP. במאמר Make your website "חסום לגישה מדומיינים אחרים" using COOP and COEP מוסבר למה זה חשוב.

ממשקי API מסוימים לאינטרנט מגבירים את הסיכון להתקפות ערוץ צדדי כמו Spectre. כדי לצמצם את הסיכון הזה, הדפדפנים מציעים סביבה מבודדת שמבוססת על הצטרפות, שנקראת "חסום לגישה מדומיינים אחרים". במצב של חסימה לגישה מדומיינים אחרים, דף האינטרנט יוכל להשתמש בתכונות בעלות הרשאות, כולל:

API תיאור
SharedArrayBuffer נדרש לשרשורים של WebAssembly. האפשרות הזו זמינה החל מגרסה 88 של Chrome ל-Android. הגרסה למחשב מופעלת כברירת מחדל בעזרת בידוד אתרים, אבל היא תדרוש מצב חסימה לגישה מדומיינים אחרים ותהיה מושבתת כברירת מחדל ב-Chrome 92.
performance.measureUserAgentSpecificMemory() זמין מגרסה 89 של Chrome.
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), החלון שפותח וחלון תיבת הדו-שיח חולקים את אותו הקשר גלישה, ולכן יש להם גישה זה לזה באמצעות ממשקי API של DOM כמו window.opener.

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

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

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

מוודאים שכל המשאבים בדף נטענים עם כותרות HTTP מסוג CORP או CORS. השלב הזה נדרש כדי לבצע את שלב 4, הפעלת 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, משאבי משנה ממקורות שונים שנטענים בלי CORS צריכים להגדיר את הכותרת Cross-Origin-Resource-Policy: cross-origin כדי להביע הסכמה להטמעה. לדוגמה, זה חל על <script>, importScripts, <link>, <video>, <iframe> וכו'.

בידוד ב-iframe

כדי להפעיל חסום לגישה מדומיינים אחרים במסמך שמוטמע ב-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) בעמודה Status.

בעיות COEP בעמודה &quot;סטטוס&quot; בחלונית &quot;רשת&quot;.

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

פרטי הבעיה ב-COEP מוצגים בכרטיסייה &quot;כותרות&quot; אחרי שלוחצים על משאב רשת בחלונית &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.example.org/check.svg?",
    "blockedURL": "https://third-party-test.example.org/check.svg?",
    "destination": "image",
    "disposition": "enforce",
    "type": "corp"
  },
  "type": "coep",
  "url": "https://cross-origin-isolation.example.com/?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.example.org/popup?report-only&coop=same-origin&",
    "type": "navigation-from-response"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.example.com/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"
}]

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

[{
  "age": 51785,
  "body": {
    "columnNumber": 18,
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "lineNumber": 83,
    "property": "postMessage",
    "sourceFile": "https://cross-origin-isolation.example.com/popup.js",
    "type": "access-from-coop-page-to-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.example.com/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.example.com/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: ממשק ה-API של JS Self-Profiling הוזכר כאחד מממשקי ה-API שדורשים בידוד ממקורות שונים, אבל הוא הוסר בעקבות השינוי האחרון בכיוון.
  • 6 במאי 2021: על סמך משוב ובעיות שדווחו, החלטנו לשנות את לוח הזמנים להגבלת השימוש ב-SharedArrayBuffer באתרים שלא חסומים לגישה מדומיינים אחרים, כך שההגבלה תתחיל בגרסה M92 של Chrome.
  • 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 זמין מגרסה 87 של Chrome. בהתאם לכך, document.domain לא ניתן לשינוי כש-self.crossOriginIsolated מחזיר את הערך true. גרסת המקור לניסיון של performance.measureUserAgentSpecificMemory() מסתיימת, והיא מופעלת כברירת מחדל ב-Chrome 89. התכונה Shared Array Buffer ב-Chrome ל-Android תהיה זמינה החל מגרסה 88 של Chrome.