מתכונים לקובצי cookie של SameSite

Chrome,‏ Firefox,‏ Edge ודפדפנים אחרים משנים את התנהגות ברירת המחדל שלהם בהתאם להצעה של IETF,‏ Incrementally Better Cookies, כך ש:

  • קובצי cookie ללא מאפיין SameSite מטופלים כ-SameSite=Lax, כלומר התנהגות ברירת המחדל היא להגביל את קובצי ה-cookie להקשרים של צד ראשון בלבד.
  • כדי לאפשר את ההכללה בהקשר של צד שלישי, חובה לציין את הערך SameSite=None; Secure בקובצי cookie לשימוש בכמה אתרים.

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

תמיכה בדפדפנים

  • Chrome: 51.
  • Edge: ‏ 16.
  • Firefox: ‏ 60.
  • Safari: 13.

מקור

תרחישים לדוגמה לשימוש בקובצי cookie בכמה אתרים או בקובצי cookie של צד שלישי

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

תוכן בתוך <iframe>

תוכן מאתר אחר שמוצג ב-<iframe> נמצא בהקשר של צד שלישי. תרחישים רגילים לדוגמה:

  • תוכן מוטמע ששותף מאתרים אחרים, כמו סרטונים, מפות, דוגמאות לקוד ופוסטים ברשתות חברתיות.
  • ווידג'טים משירותים חיצוניים, כמו תשלומים, יומנים, תכונת הזמנות ועוד.
  • ווידג'טים כמו לחצנים של רשתות חברתיות או שירותי מניעת הונאות שיוצרים <iframes> פחות בולט.

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

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

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

בקשות 'לא בטוחות' בין אתרים

'לא בטוח' עשוי להישמע כאן מדאיג, אבל הוא מתייחס לכל בקשה שעשויה לשנות את המצב. באינטרנט, אלה בעיקר בקשות POST. קובצי cookie שמסומנים בתווית SameSite=Lax נשלחים בפעולות ניווט בטוחות ברמה העליונה, כמו לחיצה על קישור כדי לעבור לאתר אחר. עם זאת, שליחת <form> לאתר אחר באמצעות POST לא כוללת קובצי cookie.

תרשים של בקשה שעוברת מדף אחד לאחר.
אם הבקשה הנכנסת משתמשת בשיטה 'בטוחה', הדף שולח קובצי cookie.

התבנית הזו משמשת לאתרים שיכולים להפנות את המשתמש לשירות מרוחק כדי לבצע פעולה כלשהי לפני שהוא חוזר, למשל, הפניה לספק זהויות של צד שלישי. לפני שהמשתמש יוצא מהאתר, מוגדר קובץ cookie שמכיל אסימון לשימוש יחיד, במטרה לבדוק את האסימון בבקשה החוזרת כדי לצמצם את היקף ההתקפות מסוג זיוף בקשה בין אתרים (CSRF). אם הבקשה החוזרת תגיע דרך POST, תצטרכו לסמן את קובצי ה-cookie בתור SameSite=None; Secure.

משאבים מרוחקים

כל משאב מרוחק בדף, כמו תגי <img> או תגי <script>, עשוי להסתמך על קובצי cookie שנשלחים עם בקשה. תרחישים נפוצים לדוגמה כוללים מעקב אחרי פיקסלים והתאמה אישית של תוכן.

הכלל הזה חל גם על בקשות שנשלחות מ-JavaScript באמצעות fetch או XMLHttpRequest. אם fetch() נקרא עם האפשרות credentials: 'include', סביר להניח שהבקשות האלה יכללו קובצי cookie. ב-XMLHttpRequest, קובצי cookie צפויים מסומנים בדרך כלל באמצעות ערך withCredentials עבור true. קובצי ה-cookie האלה חייבים להיות מסומנים בצורה מתאימה כדי שייכללו בבקשות בין אתרים.

תוכן בתוך WebView

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

ב-Android, אפליקציות ספציפיות לפלטפורמה יכולות גם להגדיר קובצי cookie ישירות באמצעות CookieManager API. בדומה לקובצי cookie שמוגדרים באמצעות כותרות או JavaScript, כדאי לכלול את הערך SameSite=None; Secure אם הם מיועדים לשימוש בכמה אתרים.

איך מטמיעים את SameSite כבר היום

מסמנים את כל קובצי ה-cookie שנדרשים רק בהקשר של צד ראשון בתור SameSite=Lax או SameSite=Strict, בהתאם לצרכים שלכם. אם לא תסמנו את קובצי ה-cookie האלה, אלא תסתמכו על התנהגות ברירת המחדל של הדפדפן לטיפול בהם, הם עשויים לפעול באופן לא עקבי בדפדפנים שונים, ויכול להיות שהם יפעילו אזהרות במסוף לכל קובץ cookie.

Set-Cookie: first_party_var=value; SameSite=Lax

חשוב לסמן את כל קובצי ה-Cookie שנדרשים בהקשר של צד שלישי בתור SameSite=None; Secure. חובה להשתמש בשני המאפיינים. אם מציינים רק את None בלי Secure, קובץ ה-cookie יידחה. כדי להתחשב בהבדלים בהטמעות בדפדפנים, יכול להיות שתצטרכו להשתמש בחלק מהאסטרטגיות למזעור ההשפעה שמתוארות בקטע טיפול בלקוחות לא תואמים.

Set-Cookie: third_party_var=value; SameSite=None; Secure

טיפול בלקוחות לא תואמים

השינויים האלה, שכוללים את None ועדכון התנהגות ברירת המחדל, עדיין חדשים יחסית, ולכן דפדפנים שונים מטפלים בהם בדרכים שונות. בדף העדכונים ב-chromium.org תוכלו למצוא רשימה של בעיות ידועות, אבל יכול להיות שהרשימה הזו לא מקיפה.

פתרון אפשרי אחד הוא להגדיר כל קובץ cookie גם בסגנון החדש וגם בסגנון הישן:

Set-cookie: 3pcookie=value; SameSite=None; Secure
Set-cookie: 3pcookie-legacy=value; Secure

דפדפנים שמטמיעים את ההתנהגות החדשה יותר מגדירים את קובץ ה-cookie עם הערך SameSite. בדפדפנים שלא מטמיעים את ההתנהגות החדשה, הערך הזה מתעלם ומגדיר את קובץ ה-cookie‏ 3pcookie-legacy. כשמעובדים קובצי cookie שכלולים, האתר צריך לבדוק קודם אם קיים קובץ cookie מהסוג החדש, ואז לעבור לקובץ cookie הקודם אם הוא לא מצליח למצוא קובץ חדש.

בדוגמה הבאה מוסבר איך לעשות זאת ב-Node.js באמצעות Express framework ו-cookie-parser, שכבת הביניים:

const express = require('express');
const cp = require('cookie-parser');
const app = express();
app.use(cp());

app.get('/set', (req, res) => {
  // Set the new style cookie
  res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true });
  // And set the same value in the legacy cookie
  res.cookie('3pcookie-legacy', 'value', { secure: true });
  res.end();
});

app.get('/', (req, res) => {
  let cookieVal = null;

  if (req.cookies['3pcookie']) {
    // check the new style cookie first
    cookieVal = req.cookies['3pcookie'];
  } else if (req.cookies['3pcookie-legacy']) {
    // otherwise fall back to the legacy cookie
    cookieVal = req.cookies['3pcookie-legacy'];
  }

  res.end();
});

app.listen(process.env.PORT);

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

לחלופין, אפשר לזהות את הלקוח באמצעות מחרוזת סוכן המשתמש כשנשלחת כותרת Set-Cookie. כדאי לעיין ברשימת הלקוחות הלא תואמים ולהשתמש בספריית זיהוי סוכן משתמש מתאימה לפלטפורמה שלכם. לדוגמה, הספרייה ua-parser-js ב-Node.js. הגישה הזו מחייבת לבצע שינוי אחד בלבד, אבל יכול להיות שריחרור נתונים על ידי סוכן המשתמש לא יתפוס את כל המשתמשים שמושפעים מכך.

תמיכה ב-SameSite=None בשפות, בספריות וב-frameworks

רוב השפות והספריות תומכות במאפיין SameSite לקובצי cookie. עם זאת, מכיוון שהוספת SameSite=None עדיין חדשה יחסית, יכול להיות שתצטרכו להתגבר על התנהגות רגילה מסוימת בינתיים. ההתנהגויות האלה מתועדות במאגר הדוגמאות של SameSite ב-GitHub.

קבלת עזרה

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