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

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

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

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

Browser Support

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

תרחישי שימוש בקובצי Cookie חוצי-אתרים או של צד שלישי

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

תוכן בתוך <iframe>

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

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

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

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

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