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

סיכום

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

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

מבוא

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

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

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

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

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

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

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

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

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

ממשק ה-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?

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

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

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

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

באתר caniuse.com אפשר למצוא את הפרטים העדכניים ביותר לגבי תמיכה בדפדפנים.

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

סיכום

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

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