עדכונים של SharedArrayBuffer ב-Android Chrome 88 וב-Chrome למחשב 92

אפשר לומר שSharedArrayBuffer לא התקבל בצורה חלקה במיוחד באינטרנט, אבל המצב משתפר. דברים שעליך לדעת:

בקצרה

  • בשלב הזה, יש תמיכה ב-SharedArrayBuffer ב-Firefox מגרסה 79 ואילך, והתמיכה תושק ב-Android Chrome 88. עם זאת, היא זמינה רק לדפים שהם cross-origin isolated.
  • התכונה SharedArrayBuffer זמינה כרגע ב-Chrome למחשב, אבל החל מ-Chrome 92 היא תוגבל לדפים מבודדים ממקורות שונים. אם אתם חושבים שלא תספיקו לבצע את השינוי הזה בזמן, תוכלו להירשם לניסיון מקור כדי לשמור על ההתנהגות הנוכחית עד לגרסה Chrome 113 לפחות.
  • אם אתם מתכוונים להפעיל בידוד בין מקורות כדי להמשיך להשתמש ב-SharedArrayBuffer, כדאי להעריך את ההשפעה של הפעולה הזו על רכיבים אחרים באתר שמשתמשים במקורות שונים, כמו מיקומי מודעות. כדי להבין את ההשפעה ולקבל הנחיות, בודקים אם נעשה שימוש ב-SharedArrayBuffer במשאבי צד שלישי כלשהם.

סקירה כללית על בידוד ממקורות שונים

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

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

אחרי שתעשו את זה, הדף לא יוכל לטעון תוכן ממקורות שונים, אלא אם המשאב יאפשר זאת באופן מפורש באמצעות כותרת Cross-Origin-Resource-Policy או כותרות CORS (Access-Control-Allow-* וכן הלאה).

יש גם Reporting API, כך שאפשר לאסוף נתונים על בקשות שנכשלו כתוצאה מ-Cross-Origin-Embedder-Policy ו-Cross-Origin-Opener-Policy.

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

בקטע קריאה נוספת בתחתית הדף הזה מפורטות הנחיות ומידע נוסף על בידוד בין מקורות שונים.

איך הגענו למצב הזה?

SharedArrayBuffer הגיע ל-Chrome 60 (ביולי 2017, למי שחושב על זמן במונחים של תאריכים ולא של גרסאות Chrome), והכול היה מצוין. למשך 6 חודשים.

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

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

כדי לצמצם את הבעיה, הקטנו את הרזולוציה של הטיימרים ברזולוציה גבוהה, כמו performance.now(). עם זאת, אפשר ליצור טיימר ברזולוציה גבוהה באמצעות SharedArrayBuffer על ידי שינוי הזיכרון בלולאה צפופה ב-Worker וקריאתו מחדש בשרשור אחר. אי אפשר היה לצמצם את הבעיה בלי לפגוע באופן משמעותי בקוד תקין, ולכן השבתנו את SharedArrayBuffer לחלוטין.

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

<iframe src="https://your-bank.example/balance.json"></iframe>
<script src="https://your-bank.example/balance.json"></script>
<link rel="stylesheet" href="https://your-bank.example/balance.json" />
<img src="https://your-bank.example/balance.json" />
<video src="https://your-bank.example/balance.json"></video>
<!-- …and more… -->

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

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

אחרי שיישמנו את הפתרונות האלה, הצגנו מחדש את SharedArrayBuffer ב-Chrome 68 (יולי 2018), אבל רק במחשב. הדרישות הנוספות של התהליך מנעו מאיתנו לעשות את אותו הדבר במכשירים ניידים. צוין גם שהפתרון של Chrome לא היה מלא, כי חסמנו רק פורמטים של נתונים 'לא נכונים', בעוד שאפשר (אף על פי שזה לא שכיח) ש-CSS/JS/תמונות תקינים בכתובות URL שאפשר לנחש יכילו נתונים פרטיים.

אנשי תקני האינטרנט התכנסו כדי למצוא פתרון מלא יותר שמתאים לכל הדפדפנים. הפתרון היה לאפשר לדפים להצהיר: "אני מוותר על היכולת שלי להכניס תוכן ממקורות אחרים לתהליך הזה בלי הסכמה שלהם". ההצהרה הזו מתבצעת באמצעות כותרות COOP ו-COEP שמוצגות עם הדף. הדפדפן אוכף את זה, ובתמורה הדף מקבל גישה אל SharedArrayBuffer וממשקי API אחרים עם יכולות דומות. מקורות אחרים יכולים להביע הסכמה להטמעת תוכן באמצעות Cross-Origin-Resource-Policy או CORS.

‫Firefox היה הדפדפן הראשון שבו הוטלה ההגבלה הזו על SharedArrayBuffer, בגרסה 79 (יולי 2020).

אחר כך, בינואר 2021, כתבתי את המאמר הזה, ואתם קראתם אותו. שלום,

וזה המצב כרגע. ב-Chrome 88, האפשרות SharedArrayBuffer חוזרת ל-Android בדפים שחסימת הגישה אליהם מדומיינים אחרים מופעלת, וב-Chrome 92, אותן דרישות מוחלות על מחשבים, גם כדי לשמור על עקביות וגם כדי להשיג חסימה מלאה לגישה מדומיינים אחרים.

דחייה של השינוי ב-Chrome למחשב

זהו חריג זמני בצורה של 'תקופת ניסיון למקור' שנותן לאנשים יותר זמן ליישם דפים מבודדים ממקורות שונים. היא מאפשרת להשתמש ב-SharedArrayBuffer בלי שהדף יהיה מבודד ממקורות שונים. תוקף החריגה יפוג ב-Chrome 113, והיא חלה רק על Chrome למחשב.

  1. שליחת בקשה לקבלת טוקן למקור.
  2. מוסיפים את הטוקן לדפים. יש שתי דרכים לעשות את זה:
    • מוסיפים תג origin-trial <meta> לראש כל דף. לדוגמה, יכול להיות שזה ייראה כך:
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • אם אפשר להגדיר את השרת, אפשר גם להוסיף את האסימון באמצעות Origin-Trialכותרת HTTP. כותרת התגובה שמתקבלת אמורה להיראות כך:
      Origin-Trial: TOKEN_GOES_HERE

קריאה נוספת

תמונת הבאנר צולמה על ידי Daniel Gregoire ב-Unsplash