เผยแพร่เมื่อวันที่ 12 มิถุนายน 2025
เมื่อวันที่ 20 พฤษภาคม 2025 ข้อกำหนดเฉพาะของ HTML ได้รับการอัปเดตเพื่อหลีกหนี <
และ >
ในแอตทริบิวต์ ซึ่งช่วยป้องกันช่องโหว่ Mutation XSS (mXSS) การเปลี่ยนแปลงนี้มีผลใน Chrome 138 ซึ่งได้รับการเลื่อนขั้นเป็นเบต้าเมื่อวันที่ 28 พฤษภาคม 2025 และจะกลายเป็นเวอร์ชันเสถียรในวันที่ 24 มิถุนายน 2025
โพสต์นี้จะอธิบายรายละเอียดผลกระทบของการเปลี่ยนแปลงการหนีค่าแอตทริบิวต์ HTML ต่อนักพัฒนาเว็บและการหยุดชะงักที่อาจเกิดขึ้น เหตุผลด้านความปลอดภัยที่อยู่เบื้องหลังการเปลี่ยนแปลงนี้อธิบายไว้ในโพสต์ที่เกี่ยวข้องในบล็อกวิศวกรรมความปลอดภัย
สิ่งที่เปลี่ยนแปลง
สมมติว่าคุณมีองค์ประกอบ <div>
ที่แอตทริบิวต์ data-content
มีค่าเป็น "<u>hello</u>"
สิ่งที่จะเกิดขึ้นเมื่อคุณอ่าน div.outerHTML
ก่อนหน้านี้ คุณจะได้รับ HTML ต่อไปนี้
<div data-content="<u>hello</u>"></div>
หลังจากการเปลี่ยนแปลง คุณจะได้รับ HTML ต่อไปนี้
<div data-content="<u>hello</u>"></div>
ก่อนหน้านี้ <
และ >
ไม่ได้ได้รับการหลีกหนีในแอตทริบิวต์ ตอนนี้อักขระทั้ง 2 ตัวนี้จะมีเครื่องหมายหลีกเสมอ
สิ่งที่ไม่เปลี่ยนแปลง
การเปลี่ยนแปลงนี้จะแก้ไขเฉพาะวิธีแปลงข้อมูลโค้ด 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
ทั้ง 2 รายการในลักษณะเดียวกันทุกประการ และทั้ง 2 กรณี 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 ด้วยนิพจน์ทั่วไป หากต้องการรับค่าของแอตทริบิวต์ ให้ใช้ DOM API ที่อธิบายไว้ในส่วนก่อนหน้า
การทดสอบจากต้นทางถึงปลายทาง
หากคุณมีพิพลิน CI/CD ที่ใช้ Chromium เพื่อสร้าง HTML และเขียนการทดสอบเพื่อเปรียบเทียบ HTML กับค่าคงที่ที่คาดไว้ การทดสอบเหล่านี้อาจใช้งานไม่ได้หากแอตทริบิวต์ใดก็ตามมี <
หรือ >
นี่เป็นข้อบกพร่องที่คาดไว้ คุณต้องอัปเดตค่าที่คาดไว้เพื่อให้ระบบหลีกอักขระ <
และ >
ทั้งหมดเป็น <
และ >,
ตามลำดับ
สรุป
บล็อกโพสต์นี้อธิบายการเปลี่ยนแปลงในข้อกำหนด HTML ซึ่งจะทำให้เบราว์เซอร์เริ่มหลีกหนี <
และ >
ในแอตทริบิวต์เพื่อปรับปรุงความปลอดภัยด้วยการป้องกันการเกิด XSS บางรายการ
การเปลี่ยนแปลงนี้จะพร้อมให้บริการแก่ผู้ใช้ทุกคนในวันที่ 24 มิถุนายน 2025 ใน Chromium (เวอร์ชัน 138) และ Firefox (เวอร์ชัน 140) ฟีเจอร์นี้ยังรวมอยู่ใน Safari 26 เบต้าด้วย ซึ่งคาดว่าจะเปิดตัวประมาณเดือนกันยายน 2025
หากคุณเชื่อว่าการเปลี่ยนแปลงนี้ทำให้เว็บไซต์ใช้งานไม่ได้และคุณไม่มีวิธีแก้ไขง่ายๆ โปรดรายงานข้อบกพร่องที่ https://issues.chromium.org/