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

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

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

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

Browser Support

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

Source

תרחישי שימוש בקובצי 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 value. דפדפנים שלא מטמיעים את ההתנהגות החדשה מתעלמים מהערך הזה ומגדירים את קובץ ה-Cookie‏ 3pcookie-legacy. כשמעבדים קובצי Cookie שכלולים בבקשה, האתר צריך קודם לבדוק אם קיים קובץ Cookie בסגנון החדש, ואם לא נמצא כזה, לחזור לקובץ Cookie מדור קודם.

בדוגמה הבאה מוצג אופן השימוש ב-Node.js, באמצעות מסגרת Express ותוכנת הביניים 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 נמצאים בכל מקום באינטרנט, ובדרך כלל צוותי פיתוח לא יודעים איפה האתר שלהם מגדיר ומשתמש בהם, במיוחד בתרחישי שימוש באתרים שונים. אם נתקלתם בבעיה, יכול להיות שאתם הראשונים שנתקלים בה, אז אל תהססו לפנות אלינו: