הפיכת האתר שלך "מבודד ממקורות שונים" באמצעות COOP ו-COEP

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

עדכונים

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

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

API תיאור
SharedArrayBuffer נדרש לשרשור של WebAssembly. התכונה הזו זמינה ב-Android Chrome 88 ואילך. הגרסה למחשב מופעלת כרגע כברירת מחדל בעזרת בידוד האתרים, אבל תידרש לה סטטוס בידוד חוצה-מקורות, והיא תושבת כברירת מחדל ב-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

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

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

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

פריסה של COOP ו-COEP כדי לבצע בידוד של האתר ממקורות שונים

שילוב של COOP ו-COEP

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

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

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

קבוצת הקשר של עיון

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

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

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

כך עושים זאת בהתאם לאופי המשאב:

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

3. שימוש בכותרת ה-HTTP של COEP לדיווח בלבד כדי להעריך משאבים מוטמעים

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

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

4. הפעלת COEP

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

בדיקה אם הבידוד הצליח באמצעות self.crossOriginIsolated

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

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

במשאבים שמעובדים במסך, כמו תמונות, קל יחסית לזהות בעיות ב-COEP, כי הבקשה תיחסם והדף יציין שחסרה תמונה. עם זאת, במשאבים שלא בהכרח יש להם השפעה חזותית, כמו סקריפטים או סגנונות, יכול להיות שלא תבחינו בבעיות שקשורות ל-COEP. במקרים כאלה, צריך להשתמש בחלונית Network (רשת) של DevTools. אם יש בעיה ב-COEP, הערך (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep) יופיע בעמודה Status.

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

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

פרטים על בעיית COEP מוצגים בכרטיסייה &#39;כותרות&#39; אחרי לחיצה על משאב רשת בחלונית &#39;רשת&#39;.

אפשר גם לקבוע את הסטטוס של iframes וחלונות קופצים באמצעות החלונית Application. עוברים לקטע Frames בצד שמאל ומרחיבים את הקטע top כדי לראות את הפירוט של מבנה המשאב.

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

הכלי לבדיקת iframe ב-Chrome DevTools

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

הכלי לבדיקת חלונות קופצים ב-Chrome DevTools

איתור בעיות באמצעות Reporting API

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

במאמר שימוש ב-Reporting API מוסבר איך מגדירים את 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"
}]

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

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

משאבים