XXE Attack Adalah: Kerentanan XML External Entity dan Cara Mencegahnya
XXE attack adalah kerentanan saat parser XML memproses external entity dari input tak tepercaya. Pelajari cara kerjanya dan cara mencegahnya per bahasa.
Pembuat Hyper Sheets & BelajarWeb.dev
XXE (XML External Entity) attack adalah kerentanan keamanan yang terjadi ketika parser XML aplikasi memproses external entity dari input yang tidak tepercaya, memungkinkan penyerang membaca file di server (misalnya /etc/passwd atau file konfigurasi), melakukan SSRF ke jaringan internal, atau memicu denial of service. Kerentanan ini masuk kategori OWASP Top 10 dan muncul justru karena parser XML default di banyak library mengizinkan external entity tanpa kamu sadari. Kabar baiknya: begitu kamu paham akar masalahnya, mencegahnya cuma butuh beberapa baris konfigurasi.
Artikel ini ditulis dari sudut pandang defensif, untuk kamu yang mengamankan aplikasi buatanmu sendiri, persis seperti materi OWASP atau PortSwigger. Kita bahas berurutan: apa itu XML entity (internal vs external) supaya kamu paham akar masalahnya, bagaimana XXE terjadi, dampaknya (baca file sensitif, SSRF, “billion laughs”), contoh payload edukatif untuk pemahaman, lalu fokus utama kita, cara mencegah XXE di PHP, Java, Python, .NET, dan Node.js, plus lapis pertahanan tambahan. Tidak ada satu pun bagian di sini yang mengajari cara menyerang sistem orang lain; semua contoh untuk mengeraskan aplikasimu sendiri.
XXE Attack Adalah… (Definisi Singkat)
XXE attack adalah serangan yang mengeksploitasi cara parser XML memproses “external entity”, referensi khusus di dalam dokumen XML yang menyuruh parser mengambil data dari sumber luar seperti file lokal atau URL. Ketika aplikasi menerima XML dari pengguna dan mem-parsingnya dengan pengaturan default yang mengizinkan external entity, penyerang bisa menyelipkan entity yang menunjuk ke file rahasia di server, lalu isi file itu ikut terbaca dan dikembalikan dalam respons. Nama lengkapnya XML External Entity injection, sering disingkat XXE atau XXEi.
Sebelum kita ke pencegahan, kamu harus benar-benar paham satu konsep dasar dulu: apa itu entity di XML. Tanpa itu, semua solusi cuma jadi hafalan.
Memahami XML Entity: Internal vs External
XML entity adalah semacam variabel atau shortcut di dalam dokumen XML, kamu mendefinisikannya sekali, lalu memanggilnya berkali-kali, dan parser akan menggantinya dengan nilai sebenarnya saat dokumen dibaca. Ada dua jenis utama: internal entity (nilainya ditulis langsung di dalam dokumen) dan external entity (nilainya diambil dari sumber luar lewat kata kunci SYSTEM atau PUBLIC). External entity inilah yang jadi sumber masalah XXE.
Entity didefinisikan di dalam blok DTD (Document Type Definition), yang biasanya ditulis di bagian <!DOCTYPE ...> di awal dokumen. Mari lihat contoh internal entity yang aman dan tidak berbahaya:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE catatan [
<!ENTITY penulis "Budi Santoso">
]>
<catatan>
<oleh>&penulis;</oleh>
</catatan>
Di sini &penulis; adalah pemanggilan entity. Parser akan menggantinya sehingga isi elemen oleh menjadi “Budi Santoso”. Nilainya ditulis langsung di dalam dokumen ("Budi Santoso"), jadi ini internal entity, tidak ada akses ke luar, tidak ada risiko.
Sekarang perhatikan versi external entity, yang strukturnya nyaris identik tapi mengandung kata kunci SYSTEM:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE catatan [
<!ENTITY penulis SYSTEM "file:///etc/hostname">
]>
<catatan>
<oleh>&penulis;</oleh>
</catatan>
Bedanya cuma satu: alih-alih string harfiah, entity penulis sekarang menunjuk ke file:///etc/hostname lewat SYSTEM. Kalau parser mengizinkan external entity, ia akan benar-benar membuka file itu dan menaruh isinya ke dalam <oleh>. Ganti /etc/hostname dengan file yang lebih sensitif, dan kamu langsung paham kenapa fitur “sepele” ini bisa jadi bencana. Itulah inti XXE: menyalahgunakan mekanisme external entity yang sebenarnya dirancang untuk kebutuhan sah (misalnya menyusun dokumen XML modular dari beberapa file).
Ada juga varian parameter entity (ditandai % alih-alih &) yang dipakai di dalam DTD itu sendiri. Varian ini penting saat aplikasi memblokir entity biasa tapi lupa memblokir DTD sepenuhnya, penyerang memakai parameter entity untuk blind XXE dan mengeksfiltrasi data lewat request keluar. Poin praktisnya: memblokir sebagian fitur saja tidak cukup; kamu harus mematikan pemrosesan DTD dari input tak tepercaya secara menyeluruh.
Bagaimana XXE Terjadi: Parser Default yang Terlalu Ramah
XXE terjadi karena banyak library XML, secara historis, mengaktifkan pemrosesan DTD dan external entity secara default, jadi aplikasi rentan bahkan tanpa developer menulis kode berbahaya apa pun. Alur serangannya sederhana: aplikasi menerima XML dari sumber tak tepercaya (body request, upload file, webhook, API), mem-parsingnya dengan konfigurasi default, dan parser dengan patuh menjalankan setiap instruksi <!ENTITY ... SYSTEM ...> yang ada di dalamnya.
Titik masuk XXE jauh lebih banyak daripada yang dibayangkan kebanyakan orang. Kamu rentan setiap kali aplikasimu mem-parsing XML yang asalnya bisa dikontrol pihak luar, misalnya:
- API atau endpoint yang menerima
Content-Type: application/xmlatautext/xml. - Upload file yang isinya XML, termasuk format yang “menyamar”, karena
.svg,.docx,.xlsx, dan.pptxsebenarnya bungkusan XML. - Webhook dan integrasi pihak ketiga yang mengirim payload XML.
- SOAP dan SAML, protokol autentikasi berbasis XML yang sangat sensitif; XXE di endpoint SAML bisa fatal.
- Feed RSS/Atom, sitemap, atau konfigurasi yang di-parse dari sumber eksternal.
Perhatikan pola berbahaya berikut dalam PHP, kode ini terlihat polos, tapi flag LIBXML_NOENT diam-diam menyuruh libxml menggantikan (substitusi) external entity:
<?php
// BERBAHAYA: LIBXML_NOENT mengaktifkan substitusi entity
$dom = new DOMDocument();
$dom->loadXML($inputTakTepercaya, LIBXML_NOENT | LIBXML_DTDLOAD);
echo $dom->textContent;
Dampak Serangan XXE
Mari bedah satu per satu.
1. Membaca File Sensitif di Server
Dampak paling klasik: penyerang membuat external entity yang menunjuk ke file di server, lalu isinya ikut terbaca dalam respons aplikasi. Target favorit di sistem Linux adalah /etc/passwd (untuk memetakan user sistem), tapi yang jauh lebih berbahaya adalah file konfigurasi aplikasi, misalnya .env yang berisi kredensial database, API key, dan secret. Sekali file itu bocor, seluruh aplikasi bisa dianggap terkompromi.
2. SSRF ke Jaringan Internal
External entity tidak cuma bisa menunjuk ke file://, tapi juga ke http://. Artinya penyerang bisa memaksa servermu mengirim request ke alamat internal yang seharusnya tidak bisa dijangkau dari luar, inilah Server-Side Request Forgery (SSRF). Target umumnya endpoint metadata cloud, dashboard admin internal, atau layanan yang cuma dengar di localhost. XXE adalah salah satu jalan paling umum menuju SSRF, jadi keduanya sering dibahas berpasangan; kalau mau mendalami vektor ini, ada materi khusus SSRF yang mengupas cara request internal ini disalahgunakan dan diblokir.
3. Denial of Service: “Billion Laughs”
Varian ini tidak membaca file apa pun, ia hanya memanfaatkan entity expansion untuk menghabiskan memori server. Dikenal sebagai billion laughs attack atau XML bomb. Idenya: entity yang merujuk ke entity lain secara berlapis, sehingga dokumen kecil beberapa ratus byte “mekar” jadi gigabytes saat di-parse, membekukan atau menjatuhkan proses.
<?xml version="1.0"?>
<!DOCTYPE bom [
<!ENTITY a "aaaaaaaaaa">
<!ENTITY b "&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;">
<!ENTITY c "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
<!ENTITY d "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
]>
<bom>&d;</bom>
Hitung efeknya: a = 10 huruf, b = 10×a = 100, c = 10×b = 1.000, d = 10×c = 10.000. Baru empat lapis. Tambah beberapa lapis lagi (e, f, g…) dan angkanya meledak ke miliaran karakter, dari sinilah nama “billion laughs”. Yang menarik: serangan DoS ini tetap bisa jalan bahkan kalau external entity sudah dimatikan, karena ini murni internal entity. Karena itu solusi paling tuntas bukan sekadar melarang SYSTEM, melainkan melarang deklarasi DTD sama sekali dari input tak tepercaya, kita bahas caranya sebentar lagi.
Contoh Payload XXE untuk Pemahaman
Bagian ini menampilkan struktur payload XXE murni untuk keperluan edukatif, supaya kamu bisa mengenali polanya saat mengaudit kode sendiri dan menulis test keamanan. Menunjukkan struktur payload adalah standar materi keamanan defensif (OWASP, PortSwigger, dan buku secure coding semuanya melakukannya). Kita bedah baris per baris, bukan untuk menyerang siapa pun, melainkan supaya kamu tahu persis apa yang sedang kamu blokir.
Berikut payload pembaca file yang paling kanonik:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<data>&xxe;</data>
Baris demi baris:
<?xml version="1.0" ...?>, deklarasi XML biasa, tidak berbahaya, hanya menandai versi dan encoding.<!DOCTYPE data [ ... ]>, pembuka blok DTD. Inilah gerbang yang harus kamu tutup. Kalau parser menolak DOCTYPE dari input tak tepercaya, seluruh serangan mati di sini.<!ENTITY xxe SYSTEM "file:///etc/passwd">, mendefinisikan external entity bernamaxxeyang menunjuk ke file/etc/passwd. Kata kunciSYSTEMinilah yang menyuruh parser mengambil sumber eksternal.<data>&xxe;</data>, memanggil entityxxe. Kalau external entity aktif, isi/etc/passwdmasuk ke sini dan berpotensi terpantul balik dalam respons aplikasi.
Untuk memahami varian SSRF, cukup ganti target file:// dengan http://:
<!DOCTYPE data [
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
]>
<data>&xxe;</data>
Alamat 169.254.169.254 adalah endpoint metadata yang lazim di lingkungan cloud dan hanya bisa diakses dari dalam server. Dengan XXE, penyerang meminjam server-mu untuk menjangkaunya. Sekali lagi: kamu tidak perlu pernah menjalankan payload ini ke sistem siapa pun. Nilai edukasinya adalah kamu jadi bisa menulis unit test yang mengirim payload semacam ini ke endpoint-mu sendiri dan memastikan parser-mu menolaknya, itu praktik secure code review yang sehat.
Cara Mencegah XXE (Fokus Utama)
Berikut konfigurasi konkret per bahasa.
PHP
Sejak libxml versi 2.9 (dipakai PHP modern), external entity sudah dinonaktifkan secara default, jadi masalah utama di PHP justru muncul saat developer sengaja menyalakannya dengan flag LIBXML_NOENT atau LIBXML_DTDLOAD. Aturan praktisnya: jangan pakai flag itu, dan tambahkan LIBXML_NONET untuk memblokir akses jaringan sebagai jaring pengaman.
<?php
// AMAN: tidak ada LIBXML_NOENT/LIBXML_DTDLOAD, plus LIBXML_NONET
$dom = new DOMDocument();
$dom->loadXML($inputTakTepercaya, LIBXML_NONET);
// external entity tidak akan disubstitusi, akses jaringan diblokir
Fungsi lama libxml_disable_entity_loader() masih sering kamu temui di tutorial jadul, tapi ia sudah deprecated sejak PHP 8.0 dan tidak lagi diperlukan pada libxml modern, cukup andalkan default yang aman dan hindari flag berbahaya. Kalau backend PHP-mu dibangun di atas framework seperti Laravel, konteks keamanan server-side seperti ini penting dipahami sejak awal; pemula bisa mulai dari panduan belajar Laravel untuk membangun fondasinya.
Java
Java (lewat DocumentBuilderFactory, SAXParserFactory, atau XMLInputFactory) secara historis mengaktifkan DTD dan external entity, jadi kamu wajib mengeraskannya secara eksplisit. Pertahanan paling ampuh dan direkomendasikan OWASP adalah satu baris: melarang deklarasi DOCTYPE.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// Pertahanan utama: tolak DOCTYPE sepenuhnya
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// Lapis tambahan (kalau DOCTYPE terpaksa harus diizinkan):
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
DocumentBuilder builder = dbf.newDocumentBuilder();
Kalau disallow-doctype-decl di-set true, dokumen apa pun yang mengandung DOCTYPE langsung ditolak dengan exception, dan itu justru yang kamu mau untuk input tak tepercaya. Ini sekaligus menutup billion laughs, karena tanpa DTD tidak ada tempat mendeklarasikan entity berlapis.
Python
Pustaka bawaan Python (xml.etree.ElementTree, xml.dom.minidom, xml.sax) punya sejarah rentan terhadap beberapa varian XXE dan XML bomb. Solusi yang direkomendasikan komunitas Python sangat sederhana: pakai defusedxml, drop-in replacement yang mematikan fitur berbahaya secara default.
# Ganti "import xml.etree.ElementTree as ET"
from defusedxml.ElementTree import parse
tree = parse("input_tak_tepercaya.xml")
root = tree.getroot()
# defusedxml otomatis memblokir DTD berbahaya, external entity, dan entity bomb
defusedxml menyediakan padanan untuk hampir semua parser standar (defusedxml.ElementTree, defusedxml.minidom, defusedxml.sax). Cukup ganti baris impor-nya dan sebagian besar risiko XXE hilang tanpa mengubah logika lain. Untuk lxml, matikan resolusi entity dan network dengan membuat parser eksplisit: etree.XMLParser(resolve_entities=False, no_network=True).
.NET (C#)
Di .NET, kuncinya adalah dua properti: DtdProcessing dan XmlResolver. Set pemrosesan DTD ke Prohibit dan kosongkan resolver supaya parser tidak pernah mengambil sumber eksternal.
var settings = new XmlReaderSettings
{
DtdProcessing = DtdProcessing.Prohibit, // tolak DTD sepenuhnya
XmlResolver = null // jangan resolve sumber eksternal
};
using var reader = XmlReader.Create(streamInput, settings);
var doc = new XmlDocument { XmlResolver = null };
doc.Load(reader);
Menyetel XmlResolver = null adalah inti pertahanannya: tanpa resolver, parser secara fisik tidak punya cara membuka file:// atau http://. Versi .NET modern memang punya default yang lebih aman, tapi menuliskannya eksplisit membuat niatmu jelas dan tahan terhadap perubahan default di masa depan.
Node.js
Kabar baik untuk ekosistem JavaScript: parser XML populer di Node.js (misalnya fast-xml-parser dan xml2js) umumnya tidak memproses DTD atau meng-expand external entity secara default, jadi relatif aman dari XXE klasik. Risiko muncul kalau kamu memakai binding ke libxml (seperti libxmljs) dan menyalakan opsi seperti noent.
// Contoh dengan libxmljs: JANGAN aktifkan noent, dan cegah akses jaringan
const libxml = require('libxmljs2');
const doc = libxml.parseXml(inputTakTepercaya, {
noent: false, // jangan substitusi entity
nonet: true, // blokir akses jaringan
dtdload: false // jangan muat DTD eksternal
});
Prinsipnya sama dengan bahasa lain: jangan aktifkan opsi yang menyalakan entity substitution, dan blokir akses jaringan. Kalau backend Node-mu masih terasa asing, memahami dasar bahasanya lewat pengantar JavaScript akan memudahkanmu membaca opsi-opsi parser seperti ini.
Pakai JSON Kalau Tidak Butuh XML
Cara paling ampuh menghilangkan XXE adalah tidak mem-parsing XML sama sekali. Kalau endpoint-mu bisa menerima JSON, gunakan JSON: JSON.parse() (dan padanannya di bahasa lain) tidak mengenal konsep DTD maupun external entity, jadi seluruh kelas serangan ini otomatis tidak berlaku. Untuk banyak API modern, XML sudah tidak diperlukan, pilih format yang lebih sederhana dan permukaan seranganmu langsung menyusut.
Validasi Input, Schema, dan WAF sebagai Lapisan Tambahan
Menonaktifkan DTD adalah pertahanan utama; validasi input dan WAF adalah lapisan pertahanan berlapis (defense in depth). Terapkan validasi sebelum parsing, misalnya menolak dokumen yang mengandung string <!DOCTYPE atau <!ENTITY di depan gerbang. Menerapkan validasi berbasis skema yang ketat juga membantu memastikan hanya struktur yang kamu harapkan yang lolos; konsepnya dibahas tuntas di materi input validation & schema. Sebagai lapis paling luar, Web Application Firewall bisa memfilter pola XXE yang umum sebelum sampai ke aplikasi, pelajari cara kerja dan keterbatasannya di pengantar WAF. Ingat: WAF itu jaring, bukan tembok. Ia mengurangi kebisingan, bukan menggantikan konfigurasi parser yang benar.
Jaga Dependency Tetap Aman
XXE sering menyelinap lewat library pihak ketiga yang diam-diam mem-parsing XML, parser SVG, pembaca dokumen Office, klien SOAP, pustaka SAML. Kamu bisa saja sudah mengeraskan parser utamamu, tapi tetap rentan lewat dependency yang belum di-patch. Rutin memperbarui dependency dan memindai kerentanannya adalah bagian tak terpisahkan dari pertahanan XXE; alurnya dibahas di materi dependency vulnerabilities.
XXE dalam Kerangka Threat Modeling (STRIDE)
STRIDE adalah kerangka threat modeling yang mengelompokkan ancaman ke enam kategori, dan XXE menyentuh beberapa di antaranya sekaligus, itulah kenapa ia dianggap serius. Memodelkan ancaman lebih awal membantumu menemukan endpoint yang mem-parsing XML sebelum penyerang menemukannya. Singkatan STRIDE: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege.
XXE paling jelas masuk dua kategori. Pertama, Information Disclosure, pembacaan file sensitif dan SSRF adalah kebocoran informasi murni. Kedua, Denial of Service, billion laughs jelas-jelas serangan DoS. Dengan memetakan setiap fitur yang menerima XML ke STRIDE, kamu langsung tahu bahwa endpoint parsing XML wajib dianalisis untuk kedua kategori itu. Cara berpikir sistematis semacam ini, mendaftar aset, jalur masuk data, dan ancaman per kategori, dibahas lengkap di materi threat modeling dengan STRIDE. Menariknya, XXE juga jadi studi kasus bagus di materi khusus XXE attack yang mengajakmu berlatih langsung mengeraskan parser di editor browser.
Kesalahan Umum Developer Soal XXE
Kesalahan paling sering seputar XXE bukan karena developer ceroboh, melainkan karena asumsi yang keliru soal cara kerja parser dan cakupan input XML. Berikut daftar jebakan yang paling banyak memakan korban, kalau kamu bisa mencoret semuanya, aplikasimu sudah jauh lebih aman dari rata-rata.
1. Percaya Parser Default Sudah Aman
Asumsi “library-nya pasti sudah aman default” adalah penyebab nomor satu. Untuk sebagian ekosistem itu memang benar sekarang (PHP libxml modern, banyak parser Node), tapi untuk Java dan Python bawaan justru sebaliknya. Jangan pernah berasumsi, buka dokumentasi parser yang kamu pakai dan set konfigurasi keras secara eksplisit.
2. Menonaktifkan Hanya Sebagian Fitur
Memblokir external-general-entities tapi lupa external-parameter-entities meninggalkan pintu untuk blind XXE. Memblokir external entity tapi mengizinkan DTD meninggalkan pintu untuk billion laughs. Pertahanan paling tuntas adalah menolak DOCTYPE sepenuhnya, sekali tutup, semua varian ikut tertutup.
3. Memvalidasi Setelah Parsing, Bukan Sebelum
XXE terjadi saat parsing, bukan setelahnya. Kalau kamu baru memvalidasi isi dokumen setelah parser selesai bekerja, kerusakan sudah terjadi, file sudah terbaca, request internal sudah terkirim. Validasi (dan penolakan DOCTYPE) harus terjadi di depan gerbang, sebelum atau saat parser membaca byte pertama.
4. Lupa Library Pihak Ketiga Juga Parse XML
Ini jebakan paling halus. Kamu berpikir “aplikasiku tidak pakai XML”, padahal fitur upload avatar menerima .svg (XML), fitur impor menerima .docx/.xlsx (XML terbungkus zip), dan integrasi login memakai SAML (murni XML). Semua itu adalah permukaan XXE. Kalau aplikasimu menerima upload file, tinjau juga praktik upload file yang aman karena format-format tersebut sering luput dari radar.
5. Menganggap XXE Kerentanan Kuno yang Sudah Punah
Karena default sebagian ekosistem membaik, sebagian orang menganggap XXE “sudah selesai”. Kenyataannya ia masih rutin ditemukan, terutama di endpoint SAML, integrasi legacy, dan library yang jarang di-update. Selama aplikasimu menyentuh XML dari luar, XXE tetap relevan untuk diperiksa.
Apa pertahanan paling tuntas terhadap serangan XXE pada input XML yang tidak tepercaya?
FAQ Seputar XXE Attack
XXE adalah apa?
XXE (XML External Entity) attack adalah kerentanan keamanan yang terjadi ketika parser XML aplikasi memproses external entity dari input yang tidak tepercaya. Akibatnya penyerang bisa membaca file sensitif di server, memicu SSRF ke jaringan internal, atau melakukan denial of service. Kerentanan ini termasuk dalam OWASP Top 10 dan berakar pada konfigurasi parser XML yang mengizinkan pemrosesan DTD dan external entity.
Bagaimana cara kerja serangan XXE?
Penyerang mengirim dokumen XML yang mengandung deklarasi DTD dengan external entity, misalnya entity yang menunjuk ke file:///etc/passwd lewat kata kunci SYSTEM. Kalau parser dikonfigurasi mengizinkan external entity, ia benar-benar membuka sumber yang ditunjuk (file lokal atau URL) dan menyisipkan isinya ke dalam dokumen, yang kemudian bisa terpantul balik dalam respons aplikasi. Serangan terjadi persis di momen parsing, sebelum kode aplikasimu sempat memvalidasi apa pun.
Bagaimana cara mencegah XXE?
Pertahanan utamanya adalah menonaktifkan pemrosesan DTD dan external entity di parser, idealnya dengan menolak deklarasi DOCTYPE sepenuhnya untuk input tak tepercaya. Contohnya: disallow-doctype-decl di Java, defusedxml di Python, DtdProcessing.Prohibit plus XmlResolver = null di .NET, hindari LIBXML_NOENT di PHP, dan jangan aktifkan noent di parser Node. Tambahkan lapisan berikut sebagai defense in depth: pakai JSON kalau tidak butuh XML, validasi input sebelum parsing, WAF, dan dependency yang selalu diperbarui.
Apakah aplikasi yang pakai JSON rentan XXE?
Umumnya tidak. Parser JSON tidak mengenal konsep DTD maupun external entity, jadi seluruh kelas serangan XXE tidak berlaku pada endpoint yang murni memproses JSON dengan JSON.parse() atau padanannya. Justru inilah salah satu alasan mengganti XML dengan JSON dianggap langkah pengerasan yang efektif. Kewaspadaan tetap perlu kalau aplikasimu menerima kedua format, atau kalau ada library yang diam-diam mengubah JSON menjadi XML di belakang layar.
Apa itu billion laughs attack?
Billion laughs (atau XML bomb) adalah varian XXE untuk denial of service. Ia mendefinisikan entity berlapis di mana setiap entity merujuk berkali-kali ke entity di bawahnya, sehingga dokumen kecil beberapa ratus byte “mekar” menjadi miliaran karakter saat di-parse, menghabiskan memori dan menjatuhkan server. Serangan ini hanya memakai internal entity, jadi ia tetap mempan meski external entity sudah dimatikan, cara paling tuntas menutupnya adalah melarang deklarasi DTD dari input tak tepercaya.
Library apa yang aman untuk parsing XML?
Tidak ada library yang otomatis “aman” tanpa konfigurasi, yang penting adalah cara kamu mengaturnya. Untuk Python, defusedxml adalah pilihan paling aman karena mematikan fitur berbahaya secara default. Di Java, parser standar aman selama kamu menyetel disallow-doctype-decl. Di .NET, XmlReader dengan DtdProcessing.Prohibit dan XmlResolver = null. Di PHP, libxml modern sudah aman selama kamu tidak menyalakan LIBXML_NOENT. Kunci umumnya sama: apa pun library-nya, matikan DTD dan external entity untuk input tak tepercaya.
Langkah Selanjutnya
Kamu sekarang sudah pegang gambaran lengkapnya: apa itu XML entity, kenapa external entity berbahaya, tiga dampak utama XXE, struktur payload untuk keperluan audit, dan, yang terpenting, konfigurasi pencegahan konkret untuk PHP, Java, Python, .NET, dan Node.js. Intinya bisa diringkas satu kalimat: matikan pemrosesan DTD dan external entity untuk semua XML yang berasal dari luar, lalu tambahkan validasi, WAF, dan dependency terkini sebagai lapisan.
Langkah paling berguna berikutnya adalah menerapkannya. Buka kode yang mem-parsing XML di aplikasimu, cocokkan dengan snippet aman di atas, dan tulis satu unit test yang mengirim payload XXE ke endpoint-mu sendiri untuk memastikan ia ditolak. Setelah itu, perluas wawasan keamananmu ke kerentanan bertetangga: mulai dari daftar lengkap OWASP Top 10 untuk peta besarnya, lalu perdalam vektor yang paling sering berpasangan dengan XXE lewat materi serangan SSRF. Keamanan bukan fitur yang selesai sekali pasang, ia kebiasaan yang kamu bangun endpoint demi endpoint. Selamat mengeraskan aplikasimu!