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

סיכום

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

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

מבוא

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

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

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

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

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

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

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

  1. באמצעות כותרת ה-HTTP Feature-Policy.
  2. עם המאפיין allow ב-iframes.

הדרך הקלה ביותר להשתמש ב-Feature Policy היא לשלוח את כותרת ה-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 ב-iframes, אבל ב-Chrome 74 נוסף JavaScript API.

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

דוגמה

הדוגמה הבאה ממחישה את התוצאות של שליחת המדיניות 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"]

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

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

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

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

  • אתם מוזמנים לעיין בהדגמות של Feature Policy Kitchen Sink. יש בו דוגמאות לכל מדיניות שמוטמעת ב-Blink.
  • אתם יכולים לראות את רשימת שמות התכונות במקור של Chrome.
  • שולחים שאילתה document.featurePolicy.allowedFeatures() ב-about:blank כדי למצוא את הרשימה:
        ["geolocation",
         "midi",
         "camera",
         "usb",
         "magnetometer",
         "fullscreen",
         "animations",
         "payment",
         "picture-in-picture",
         "accelerometer",
         "vr",
        ...
  • בודקים ב-chromestatus.com את כללי המדיניות שהוטמעו או שהם משוקללים ב-Blink.

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

שאלות נפוצות

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

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

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

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

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

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

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

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

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

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

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

אילו דפדפנים תומכים ב-Feature Policy?

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

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

סיכום

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

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