מבוא למדיניות בנושא תכונות

אריק בידלמן

סיכום

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

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

מבוא

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

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

כמה דוגמאות למה שאפשר לעשות בעזרת המדיניות בנושא תכונות:

  • אפשר לשנות את התנהגות ברירת המחדל של autoplay בסרטונים בנייד ובסרטונים של צד שלישי.
  • הגבלת השימוש של אתר בממשקי API רגישים כמו camera או microphone.
  • מתן הרשאה למסגרות iframe להשתמש ב-API fullscreen.
  • חסימת השימוש בממשקי API מיושנים, כמו XHR סינכרוני ו-document.write().
  • חשוב לוודא שהתמונות בגודל מתאים (למשל, למנוע התכווצות הפריסה) ושהן לא גדולות מדי לאזור התצוגה (למשל, בזבוז רוחב הפס של המשתמש).

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

שימוש במדיניות התכונות

במדיניות התכונות יש שתי דרכים לשלוט בתכונות:

  1. דרך כותרת ה-HTTP Feature-Policy.
  2. עם המאפיין allow במסגרות iframe.

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

Feature-Policy: <feature> <allow list origin(s)>

רשימת ההרשאות המקורית יכולה לכלול כמה ערכים שונים:

  • *: אפשר להשתמש בתכונה הזו בהקשרים של גלישה ברמה העליונה ובהקשרי גלישה מקננים (iframes).
  • 'self': אפשר להשתמש בתכונה הזו בהקשרים של גלישה ברמה העליונה ובהקשרים של גלישה בתוך מקור באותו מקור. היא אסורה במסמכים ממקורות שונים בהקשרים של גלישה בתצוגת עץ.
  • 'none': התכונה אסורה בהקשרים של גלישה ברמה העליונה ואסורה בהקשרים של גלישה בתוך רכיב.
  • <origin(s)>: מקורות ספציפיים שעבורם יש להפעיל את המדיניות (למשל, https://example.com).

דוגמה

נניח שרצית לחסום את השימוש של כל התוכן ב-Geolocation API באתר שלך. אפשר לעשות זאת על ידי שליחת רשימת היתרים חד-משמעית של 'none' לתכונה geolocation:

Feature-Policy: geolocation 'none'

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

הפרת המדיניות בנושא מיקום גיאוגרפי
הפרת המדיניות בנושא מיקום גיאוגרפי שהוגדר.

במקרים אחרים כדאי לצמצם קצת את המדיניות הזו. אנחנו יכולים לאפשר למקור שלנו להשתמש ב-Geolocation API אבל למנוע גישה של תכנים של צד שלישי אליו על ידי הגדרה של 'self' ברשימת ההיתרים:

Feature-Policy: geolocation 'self'

מאפיין ה-iframe allow

הדרך השנייה להשתמש במדיניות בנושא תכונות היא שליטה בתוכן בתוך iframe. המאפיין allow משמש לציון רשימת כללי מדיניות לתוכן מוטמע:

<!-- Allow all browsing contexts within this iframe to use fullscreen. -->
<iframe src="https://example.com..." allow="fullscreen"></iframe>

<!-- Equivalent to: -->
<iframe src="https://example.com..." allow="fullscreen *"></iframe>

<!-- Allow only iframe content on a particular origin to access the user's location. -->
<iframe
  src="https://another-example.com/demos/..."
  allow="geolocation https://another-example.com"
></iframe>

מה לגבי מאפייני iframe הקיימים?

לחלק מהתכונות שנשלטות על ידי מדיניות התכונות יש מאפיין לשליטה בהתנהגות שלהן. לדוגמה, <iframe allowfullscreen> הוא מאפיין שמאפשר לתוכן ב-iframe להשתמש ב-API HTMLElement.requestFullscreen(). יש גם את המאפיינים allowpaymentrequest ו-allowusermedia שמאפשרים להשתמש ב-Payment Request API וב-getUserMedia() בהתאמה.

כדאי לנסות להשתמש במאפיין allow במקום במאפיינים הישנים האלה, במידת האפשר. במקרים שבהם צריך לתמוך בתאימות לאחור באמצעות המאפיין allow עם מאפיין מקביל מדור קודם, אין בעיה לגמרי (למשל, <iframe allowfullscreen allow="fullscreen">). חשוב לשים לב שהמדיניות המגבילה יותר היא המנצחת. לדוגמה, לרכיב ה-iframe הבא אין הרשאה להיכנס למסך מלא כי allow="fullscreen 'none'" מגביל יותר מ-allowfullscreen:

<!-- Blocks fullscreen access if the browser supports feature policy. -->
<iframe allowfullscreen allow="fullscreen 'none'" src="..."></iframe>

שליטה על כמה כללי מדיניות בו-זמנית

אפשר לשלוט בכמה תכונות בו-זמנית על ידי שליחת כותרת ה-HTTP עם רשימה מופרדת של ; של הוראות מדיניות:

Feature-Policy: unsized-media 'none'; geolocation 'self' https://example.com; camera *;

או על ידי שליחת כותרת נפרדת לכל מדיניות:

Feature-Policy: unsized-media 'none'
Feature-Policy: geolocation 'self' https://example.com
Feature-Policy: camera *;

הדוגמה הזו אמורה:

  • לא ניתן להשתמש ב-unsized-media בכל הקשרי הגלישה.
  • המדיניות אוסרת את השימוש ב-geolocation בכל הקשרי הגלישה, מלבד המקור של הדף עצמו ו-https://example.com.
  • מתן גישה ל-camera לכל הקשרי הגלישה.

דוגמה – הגדרת מספר כללי מדיניות ב-iframe

<!-- Blocks the iframe from using the camera and microphone
     (if the browser supports feature policy). -->
<iframe allow="camera 'none'; microphone 'none'"></iframe>

ממשק API של JavaScript

בגרסת Chrome 60 נוספה תמיכה בכותרת ה-HTTP Feature-Policy ובמאפיין allow במסגרות iframe, אבל ה-JavaScript API נוסף ב-Chrome 74.

ה-API הזה מאפשר לקוד בצד הלקוח לקבוע אילו תכונות מותרות בדף, במסגרת או בדפדפן. אפשר לגשת לדברים הטובים ביותר דרך document.featurePolicy למסמך הראשי או frame.featurePolicy למסגרות iframe.

דוגמה

הדוגמה הבאה ממחישה את התוצאות של שליחת מדיניות של Feature-Policy: geolocation 'self' באתר https://example.com:

/* @return {Array<string>} List of feature policies allowed by the page. */
document.featurePolicy.allowedFeatures();
// → ["geolocation", "midi",  "camera", "usb", "autoplay",...]

/* @return {boolean} True if the page allows the 'geolocation' feature. */
document.featurePolicy.allowsFeature('geolocation');
// → true

/* @return {boolean} True if the provided origin allows the 'geolocation' feature. */
document.featurePolicy.allowsFeature(
  'geolocation',
  'https://another-example.com/'
);
// → false

/* @return {Array<string>} List of feature policies allowed by the browser
regardless of whether they are in force. */
document.featurePolicy.features();
// → ["geolocation", "midi",  "camera", "usb", "autoplay",...]

/* @return {Array<string>} List of origins (used throughout the page) that are
   allowed to use the 'geolocation' feature. */
document.featurePolicy.getAllowlistForFeature('geolocation');
// → ["https://example.com"]

רשימת כללי מדיניות

על אילו תכונות ניתן לשלוט באמצעות המדיניות בנושא תכונות?

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

בשלב זה, יש כמה דרכים לראות באילו תכונות ניתן לשלוט.

        ["geolocation",
         "midi",
         "camera",
         "usb",
         "magnetometer",
         "fullscreen",
         "animations",
         "payment",
         "picture-in-picture",
         "accelerometer",
         "vr",
        ...
  • בדקו ב-chromestatus.com את כללי המדיניות שהוטמעו או שנמצאים בבדיקה ב-Blink.

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

שאלות נפוצות

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

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

חשוב יותר להתייחס לכללי מדיניות אחרים כמו document-write ו-sync-xhr. הפעלה של תוספים כאלה עלולה לגרום לשיבושים בתוכן של צד שלישי, כמו מודעות. מצד שני, אפשר להיעזר ב-Feature Policy כדי לוודא שהדפים שלכם לא משתמשים בממשקי ה-API הגרועים האלה אף פעם!

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

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

האם יש דרך לדווח על הפרות מדיניות לשרת שלי?

Reporting API כבר עובד! בדומה לאופן שבו אתרים יכולים להביע הסכמה לקבלת דוחות על הפרות של CSP או על הוצאה משימוש, תוכלו לקבל דיווחים על הפרות של המדיניות בנושא תכונות באופן כללי.

מהם כללי הירושה לגבי תוכן iframe?

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

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

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

אילו דפדפנים תומכים ב'מדיניות תכונות'?

תוכלו לעיין ב-caniuse.com לקבלת פרטים עדכניים על התמיכה בדפדפן.

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

סיכום

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

מקורות מידע נוספים: