Dipublikasikan: 12 Juni 2025
Pada 20 Mei 2025, spesifikasi HTML
diperbarui untuk meng-escape <
dan >
dalam
atribut, sehingga membantu mencegah kerentanan
XSS mutasi (mXSS). Perubahan ini diterapkan di Chrome 138, yang dipromosikan ke Beta pada
28 Mei 2025, dan akan menjadi Stabil pada 24 Juni 2025.
Postingan ini menjelaskan dampak perubahan escape atribut HTML pada developer web dan potensi kerusakan; alasan keamanan di balik perubahan ini dijelaskan dalam postingan terkait di blog Security Engineering.
Apa yang berubah
Misalkan Anda memiliki elemen <div>
yang atribut data-content
-nya memiliki
nilai "<u>hello</u>"
. Apa yang terjadi jika Anda membaca div.outerHTML
?
Sebelumnya, Anda akan mendapatkan HTML berikut:
<div data-content="<u>hello</u>"></div>
Setelah perubahan, Anda akan mendapatkan HTML berikut:
<div data-content="<u>hello</u>"></div>
Sebelumnya, <
atau >
tidak di-escape dalam atribut. Sekarang, kedua karakter
ini selalu di-escape.
Apa yang tidak berubah
Perubahan ini secara eksklusif mengubah cara fragmen HTML dikonversi kembali menjadi
representasi string selama serialisasi. Dampaknya terbatas pada skenario
saat properti innerHTML
atau outerHTML
diakses, atau saat
metode getHTML()
dipanggil pada elemen. Operasi ini menggunakan struktur DOM
yang ada dan menghasilkan representasi HTML tekstual.
Perubahan ini tidak memengaruhi penguraian HTML. Pertimbangkan HTML berikut:
<div id="div1" data-content="<u>hello</u>"></div>
<div id="div2" data-content="<u>hello</u>"></div>
Kedua div
akan diuraikan dengan cara yang sama persis dan dalam kedua kasus tersebut,
div.dataset.content
akan menampilkan "<u>hello</u>"
.
Apa yang tidak akan rusak?
Jika Anda menggunakan DOM API, seperti
getAttribute
,
getAttributeNS
,
dataset
,
atau
attributes
,
untuk mengambil nilai atribut, API tersebut akan menampilkan nilai yang didekode sama seperti
sebelumnya, khususnya dengan <
dan >
yang didekode.
Perhatikan contoh berikut, yang menampilkan semua baris console.log
akan mencatat ke dalam 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);
Apa yang dapat rusak?
innerHTML dan outerHTML untuk mendapatkan atribut
Jika Anda menggunakan innerHTML
atau outerHTML
untuk mengekstrak nilai atribut, kode Anda dapat rusak. Perhatikan contoh berikut, meskipun sedikit rumit:
<div data-content="<u>"></div>
const div = document.querySelector("div");
const content = div.outerHTML.match(/"([^"]+)"/)[1];
console.log(content);
Kode ini akan menunjukkan perilaku yang berbeda setelah perubahan ini. Sebelumnya,
content
akan sama dengan "<u>"
, tetapi sekarang menjadi "<u>"
.
Perhatikan bahwa penguraian HTML dengan ekspresi reguler tidak direkomendasikan. Jika Anda perlu mendapatkan nilai atribut, gunakan DOM API yang dijelaskan di bagian sebelumnya.
Pengujian menyeluruh
Jika Anda memiliki pipeline CI/CD tempat Anda menggunakan Chromium untuk membuat HTML, dan
Anda telah menulis pengujian untuk membandingkan HTML dengan nilai yang diharapkan statis, pengujian ini
dapat rusak jika atribut apa pun berisi <
atau >
.
Ini adalah kerusakan yang diharapkan—Anda perlu memperbarui nilai yang diharapkan sehingga semua
karakter <
dan >
masing-masing di-escape ke <
dan >,
.
Ringkasan
Postingan blog ini menjelaskan perubahan pada spesifikasi HTML yang akan menyebabkan browser mulai meng-escape <
dan >
dalam atribut untuk meningkatkan keamanan dengan mencegah beberapa instance mutasi XSS.
Perubahan ini akan tersedia untuk semua pengguna pada 24 Juni 2025 di Chromium (versi 138) dan Firefox (versi 140). Fitur ini juga disertakan dalam Safari 26 Beta yang akan dirilis sekitar September 2025.
Jika Anda yakin bahwa perubahan ini merusak situs Anda dan Anda tidak memiliki cara yang mudah untuk memperbaikinya, laporkan bug di https://issues.chromium.org/.