תאריך פרסום: 12 ביוני 2025
ב-20 במאי 2025 המפרט של HTML עודכן כדי להימנע מהצגת תווים <
ו->
בתווים בריחה (escape) במאפיינים, וכך למנוע נקודות חולשה של XSS מוטציה (mXSS). השינוי הזה הושק ב-Chrome 138, ששודרג לגרסת בטא ב-28 במאי 2025 ויהפוך לגרסה יציבה ב-24 ביוני 2025.
בפוסט הזה מוסבר בפירוט איך השינוי בבריחה של מאפיין ה-HTML משפיע על מפתחי אתרים ועל שיבושים פוטנציאליים. ההסבר על ההצדקה הביטחונית לשינוי הזה מופיע בפוסט קשור בבלוג של Security Engineering.
מה השתנה
נניח שיש לכם רכיב <div>
שהערך של המאפיין data-content
שלו הוא "<u>hello</u>"
. מה קורה כשקוראים את div.outerHTML
?
בעבר, הקוד ה-HTML היה נראה כך:
<div data-content="<u>hello</u>"></div>
אחרי השינוי, תקבלו את הקוד הבא ב-HTML:
<div data-content="<u>hello</u>"></div>
בעבר, לא בוצעה בריחה של <
או של >
במאפיינים. עכשיו, שני התווים האלה תמיד מקבלים תווי בריחה.
מה לא השתנה
השינוי משנה באופן בלעדי את האופן שבו קטעי HTML מומרים חזרה לייצוג מחרוזת במהלך שרשור. ההשפעה מוגבלת לתרחישים שבהם מתבצעת גישה למאפיינים innerHTML
או outerHTML
, או כשמתבצעת קריאה לשיטה getHTML()
ברכיב. הפעולות האלה מבוססות על מבנה ה-DOM הקיים ויוצרות ייצוג טקסטואלי של HTML.
השינוי הזה לא משפיע על ניתוח ה-HTML. נבחן את הקוד הבא ב-HTML:
<div id="div1" data-content="<u>hello</u>"></div>
<div id="div2" data-content="<u>hello</u>"></div>
שני הערכים של div
ימועדו באותו אופן, ובשני המקרים הפונקציה div.dataset.content
תחזיר את הערך "<u>hello</u>"
.
מה לא יתקלקל?
אם משתמשים ב-DOM API כלשהו, כמו getAttribute
, getAttributeNS
, dataset
או attributes
, כדי לאחזר ערכי מאפיינים, הם יחזירו את אותם ערכים מפוענחים כמו קודם, במיוחד עם <
ו->
מפוענחים.
בדוגמה הבאה, כל השורות של console.log
יתועדו ביומן "<u>"
:
<div data-content="<u>"></div>
const div = document.querySelector("div");
// All of the following will log "<u>"
console.log(div.getAttribute("data-content"));
console.log(div.dataset.content);
console.log(div.attributes['data-content'].value);
מה יכול להישבר?
innerHTML ו-outerHTML כדי לקבל מאפיינים
אם משתמשים ב-innerHTML
או ב-outerHTML
כדי לחלץ את הערך של מאפיין, הקוד עלול להשתבש. הנה דוגמה מעט מורכבת:
<div data-content="<u>"></div>
const div = document.querySelector("div");
const content = div.outerHTML.match(/"([^"]+)"/)[1];
console.log(content);
הקוד הזה יפעל בצורה שונה אחרי השינוי. בעבר, הערך של content
היה שווה ל-"<u>"
, אבל עכשיו הוא "<u>"
.
חשוב לזכור שלא מומלץ לנתח HTML באמצעות ביטויים רגולריים. אם אתם צריכים לקבל ערך של מאפיין, השתמשו בממשקי ה-API של DOM שמתוארים בקטעים הקודמים.
בדיקות מקצה לקצה
אם יש לכם צינור עיבוד נתונים של CI/CD שבו אתם משתמשים ב-Chromium כדי ליצור HTML, וכתבתם בדיקות כדי להשוות את ה-HTML לערך סטטי צפוי, יכול להיות שהבדיקות האלה יכשלו אם מאפיין כלשהו מכיל את הערכים <
או >
.
זוהי שגיאה צפויה – צריך לעדכן את הערך הצפוי כך שכל התווים <
ו->
יהיו עם תווי בריחה (escape) ל-<
ו->,
, בהתאמה.
סיכום
בפוסט הזה בבלוג תיארנו שינוי במפרט HTML שיגרום לדפדפנים להתחיל להשתמש בהימלטות (escape) של <
ו->
במאפיינים כדי לשפר את האבטחה על ידי מניעת מקרים מסוימים של XSS מוטציה.
השינוי יהיה זמין לכל המשתמשים ב-24 ביוני 2025 ב-Chromium (גרסה 138) וב-Firefox (גרסה 140). הוא נכלל גם בגרסת הבטא של Safari 26, שצפויה לצאת בסביבות ספטמבר 2025.
אם לדעתכם השינוי הזה גרם לשיבוש באתר ואין לכם דרך קלה לתקן אותו, תוכלו לשלוח דיווח על באג בכתובת https://issues.chromium.org/.