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

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

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