Ringkasan eksekutif
Saya baca pengumuman Go Security team yang di-forward ke oss-security soal dua CVE di golang.org/x/net/html: satu soal parser yang bisa dibikin lambat secara kuadratik, satu soal parser yang bisa salah menebak namespace saat merender ulang HTML. Dua-duanya bug di level parser internal, bukan di API publik yang sering kita panggil langsung, tapi efeknya kena ke siapa pun yang parsing HTML tidak terpercaya dengan paket ini.
Masalah yang diselesaikan
Yang pertama, CVE-2026-78661, ada di fungsi addText dan fosterParent. Waktu parser menggabungkan text node yang berdekatan, kodenya pakai pola n.Data += text — tiap kali ada token teks baru, Go harus realokasi dan copy ulang seluruh string yang sudah terkumpul sejauh ini. Itu pola klasik yang berujung O(n²): kalau inputnya punya banyak potongan teks pendek yang dipisah oleh closing tag yang diabaikan parser (contoh yang disebut di laporan: tag semacam </a> yang nggak valid di posisi itu), jumlah alokasi dan copy byte-nya meledak kuadratik terhadap ukuran input. Dari sudut pandang keamanan ini DoS vector yang lumayan jahat karena payload-nya bisa kecil tapi bikin CPU/memory parsing melonjak jauh dari linear. Ditemukan oleh Markus Magnuson, tercatat sebagai Go issue 82224.
Yang kedua, CVE-2026-97045, ada di childTextNodesAreLiteral, fungsi yang menentukan apakah konten teks di dalam elemen foreign-namespace (misalnya SVG/MathML) harus diperlakukan sebagai raw text literal saat dirender. Sebelum patch, fungsi ini jalan ke atas lewat ancestor chain tapi berhenti begitu nemu HTML integration point terdekat. Masalahnya, integration point itu sendiri bisa saja adalah elemen yang kena foster-parenting ke dalam foreign namespace lain. Akibatnya, kalau hasil parsing itu dirender ulang jadi HTML string dan di-reparse (misalnya oleh browser), subtree-nya bisa ditafsirkan berada di namespace yang berbeda dari yang dimaksud parser asli. Ini bukan cuma soal output salah — ini kelas bug parser-differential, yang kalau dieksploitasi bisa membuka jalan buat konten yang tadinya dianggap teks aman berubah jadi markup aktif setelah re-parse. Dilaporkan oleh Ali Sherif, tercatat sebagai Go issue 82622.
Fitur utama dan contoh kode
Untuk CVE-2026-78661, perbaikannya mengubah strategi akumulasi: bukan lagi concat string berulang, tapi numpuk byte ke buffer per-node dulu, dan baru dijadikan string sekali di akhir parsing. Ilustrasi pola before/after-nya (ini contoh saya, bukan kutipan diff resmi karena diff lengkapnya tidak dipublikasikan di pengumuman ini):
// Sebelum (ilustrasi) — setiap panggilan realokasi & copy seluruh string
n.Data += text // O(n) per token, O(n^2) total untuk banyak token pendek
// Sesudah (ilustrasi, sesuai deskripsi patch) — akumulasi di []byte,
// materialize ke string cuma sekali setelah parsing kelar
n.dataBuf = append(n.dataBuf, text...)
// ... di akhir proses parse:
n.Data = string(n.dataBuf)Untuk CVE-2026-97045, perbaikannya adalah selalu menyusuri full ancestor chain dan memverifikasi bahwa setiap transisi dari namespace non-empty memang terjadi persis di HTML integration point, bukan cuma berhenti di integration point pertama yang ketemu.
Kedua bug ini kena ke siapa pun yang memanggil html.Parse atau fungsi render dari golang.org/x/net/html atas input yang tidak dipercaya — termasuk dependency yang memakainya secara transitif. Contoh pola pemakaian yang relevan (ilustrasi saya, bukan dari sumber):
import (
"net/http"
"golang.org/x/net/html"
)
func handler(w http.ResponseWriter, r *http.Request) {
doc, err := html.Parse(r.Body) // body request = input tidak terpercaya
if err != nil {
http.Error(w, "bad html", http.StatusBadRequest)
return
}
_ = doc
}Dampak dan catatan upgrade
Pengumuman ini datang dari milis resmi golang-announce dan di-forward ke oss-security oleh Alan Coopersmith. Yang perlu dicek: apakah service Anda (langsung atau lewat dependency) memanggil parser HTML dari golang.org/x/net/html terhadap input dari luar — misalnya sanitizer HTML, proxy konten, atau tool scraping. Langkah paling aman ya update dependency-nya:
go get -u golang.org/x/net@latest
go mod tidySetelah itu jalankan ulang test suite, terutama kalau Anda punya test yang parsing HTML dengan konten SVG/MathML bercampur, karena perubahan di childTextNodesAreLiteral menyentuh logika resolusi namespace tadi. Detail lengkap dan nomor rilis resmi ada di Go issue 82224 (CVE-2026-78661) dan Go issue 82622 (CVE-2026-97045).
---
Pertama diumumkan di oss-security mailing list. Baca sumber aslinya untuk detail lengkap.