הגנה על המשאבים שלך מפני מתקפות באינטרנט באמצעות התכונה 'אחזור מטא-נתונים'

למנוע דליפות מידע ממקורות שונים, כמו CSRF, XSSI.

למה חשוב לכם לבודד את משאבי האינטרנט שלכם?

אפליקציות אינטרנט רבות חשופות למתקפות cross-origin, כמו Cross-site Request Forgery (CSRF), הכללה של סקריפטים חוצי אתרים (XSSI), התקפות תזמון, דליפות מידע ממקורות שונים או התקפות דרך ערוץ צדדי בביצוע ספקולטיבי (Spectre).

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

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

תאימות דפדפן

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

תמיכה בדפדפן

  • 76
  • 79
  • 90
  • 16.4

מקור

רקע

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

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

חדש: מטא-נתונים של אחזור

כותרות בקשות לאחזור מטא נתונים הן תכונת אבטחה חדשה של פלטפורמת אינטרנט, שנועדה לעזור לשרתים להגן על עצמם מפני התקפות ממקורות שונים. מתן מידע על ההקשר של בקשת HTTP בקבוצה של כותרות Sec-Fetch-* מאפשר לשרת המגיב להחיל מדיניות אבטחה לפני עיבוד הבקשה. כך מפתחים יכולים להחליט אם לאשר או לדחות בקשה על סמך הדרך שבה היא בוצעה וההקשר שבו ייעשה בה שימוש. כך המפתחים יוכלו להגיב רק לבקשות לגיטימיות שנשלחו על ידי האפליקציה שלהם.

מאותו מקור
בקשות שמקורן באתרים שנשלחים על ידי השרת שלך (same-origin) ימשיכו לפעול. בקשת אחזור מ-https://site.example למשאב https://site.example/foo.json ב-JavaScript גורמת לדפדפן לשלוח את כותרת בקשת ה-HTTP 'Sec Fetch-Site: same-origin'.
באתרים שונים
השרת עשוי לדחות בקשות זדוניות מאתרים שונים בגלל ההקשר הנוסף בבקשת ה-HTTP שמסופקת על ידי כותרות Sec-Fetch-*. תמונה ב-https://evil.example שהגדירה את המאפיין src של אלמנט img ל-'https://site.example/foo.json' גורמת לדפדפן לשלוח את כותרת בקשת ה-HTTP 'Sec-Fetch-Site: Cross-site'.

Sec-Fetch-Site

תמיכה בדפדפן

  • 76
  • 79
  • 90
  • 16.4

מקור

Sec-Fetch-Site מורה לשרת איזה אתר שלח את הבקשה. הדפדפן מגדיר את הערך הזה לאחת מהאפשרויות הבאות:

  • same-origin, אם הבקשה נשלחה על ידי האפליקציה שלך (למשל site.example)
  • same-site, אם הבקשה נשלחה על ידי תת-דומיין של האתר (למשל bar.site.example)
  • none, אם הבקשה נגרמה במפורש על ידי אינטראקציה של המשתמש עם סוכן המשתמש (למשל, לחיצה על סימנייה)
  • cross-site, אם הבקשה נשלחה על ידי אתר אחר (למשל evil.example)

Sec-Fetch-Mode

תמיכה בדפדפן

  • 76
  • 79
  • 90
  • 16.4

מקור

Sec-Fetch-Mode מציין את המצב של הבקשה. הנתון הזה תואם בערך לסוג הבקשה ומאפשר לכם להבחין בין טעינת משאבים לבקשות ניווט. לדוגמה, יעד navigate מציין בקשת ניווט ברמה העליונה, ואילו היעד no-cors מציין בקשות למשאבים כמו טעינת תמונה.

Sec-Fetch-Dest

תמיכה בדפדפן

  • 80
  • 80
  • 90
  • 16.4

מקור

Sec-Fetch-Dest חושף את היעד של בקשה (למשל, אם תג script או img גרם למשאב שהדפדפן ביקש).

כיצד להשתמש ב'אחזור מטא-נתונים' כדי להגן מפני התקפות ממקורות שונים

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

יישום מדיניות בנושא בידוד משאבים

מדיניות בנושא בידוד משאבים מונעת מאתרים חיצוניים לבקש את המשאבים שלך. חסימת תנועה כזו מצמצמת את נקודות החולשה הנפוצות באתרים שונים, כמו CSRF, XSSI, תזמון מתקפות ודליפות מידע ממקורות שונים. ניתן להפעיל את המדיניות הזו בכל נקודות הקצה של האפליקציה, והיא תאפשר את כל הבקשות למשאבים שמגיעות מהאפליקציה שלכם, כמו גם ניווטים ישירים (באמצעות בקשת GET HTTP). הלוגיקה הזו יכולה לבטל את ההסכמה לנקודות קצה (endpoints) שאמורות להיטען בהקשר של כמה אתרים (למשל, נקודות קצה שנטענו באמצעות CORS).

שלב 1: מתירים בקשות מדפדפנים שלא שולחים מטא-נתונים של אחזור

מכיוון שלא כל הדפדפנים תומכים באחזור מטא-נתונים, עליך לאשר בקשות שלא מגדירות כותרות Sec-Fetch-*. לשם כך, עליך לבדוק אם ה-sec-fetch-site קיים.

if not req['sec-fetch-site']:
  return True  # Allow this request

שלב 2: מתירים בקשות באותו אתר או ביוזמת הדפדפן

יתקבלו בקשות שלא מגיעות מהקשר בין מקורות (כמו evil.example). במיוחד, אלו הן הבקשות:

  • מקור מהאפליקציה שלכם (למשל, בקשת מקור זהה שבה site.example מבקשת את site.example/foo.json תמיד תהיה מותרת).
  • מקורם מתת-הדומיינים שלכם.
  • נגרמות באופן מפורש על ידי אינטראקציה של המשתמש עם סוכן המשתמש (למשל, ניווט ישיר או לחיצה על סימנייה וכו').
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
  return True  # Allow this request

שלב 3: הפעלת ניווט פשוט ברמה העליונה ו-iFrame

כדי להבטיח שעדיין ניתן יהיה לקשר את האתר שלך מאתרים אחרים, עליך לאפשר ניווט פשוט ברמה העליונה (HTTP GET).

if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
  # <object> and <embed> send navigation requests, which we disallow.
  and req['sec-fetch-dest'] not in ('object', 'embed'):
    return True  # Allow this request

שלב 4: מבטלים את ההסכמה לשימוש בנקודות קצה שמטרתן לספק תנועה מאתרים שונים (אופציונלי)

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

  • נקודות קצה שמיועדות לגישה ממקורות שונים: אם האפליקציה שלך מציגה נקודות קצה שמופעלות בהן CORS, עליך לבטל את ההסכמה שלהן באופן מפורש לבידוד משאבים כדי להבטיח שבקשות מאתרים שונים לנקודות הקצה האלה עדיין אפשריות.
  • משאבים ציבוריים (למשל, תמונות, סגנונות וכו'): כמו כן, ניתן לקבל פטור ממשאבים ציבוריים ולא מאומתים שאמורים להיות ניתנים לטעינה בין מקורות מאתרים אחרים.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
  return True

שלב 5: דחייה של כל הבקשות האחרות שנשלחות מאתרים שונים ולא מאפשרות ניווט

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

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

# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
  # Allow requests from browsers which don't send Fetch Metadata
  if not req['sec-fetch-site']:
    return True

  # Allow same-site and browser-initiated requests
  if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
    return True

  # Allow simple top-level navigations except <object> and <embed>
  if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
    and req['sec-fetch-dest'] not in ('object', 'embed'):
      return True

  # [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
  if req.path in ('/my_CORS_endpoint', '/favicon.png'):
    return True

  # Reject all other requests that are cross-site and not navigational
  return False

פריסת מדיניות בידוד משאבים

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

זיהוי ותיקון הפרות מדיניות

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

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

אכיפת מדיניות בידוד משאבים

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

קריאה נוספת