XXE (XML External Entity Attack) — Security

Apa itu XXE? XML External Entity (XXE) adalah serangan terhadap aplikasi yang mem-parsing XML dari input user. Jika parser mengizinkan external entities…

XXE (XML External Entity) adalah serangan terhadap aplikasi yang mem-parsing XML dari user. Bayangin formulir yang punya kolom ajaib bertuliskan "tempel isi file ini di sini". Kalau mesin pengisi formulirnya nurut, siapa pun yang mengisi kolom itu dengan alamat file rahasia bisa membuat isinya ikut tercetak. Di XML, kolom ajaib itu namanya external entity, dan mesinnya adalah XML parser.

🧪 Tebakan cepat: fitur parser apa yang, kalau dibiarkan aktif, membuka pintu XXE: external entities, komentar XML, atau encoding UTF-8? Tebak dulu, jawabannya ada di bagian "Cara memperbaiki".

Entity: nilai yang ditunjuk

Entity di XML itu seperti singkatan yang nanti diganti nilainya. Yang normal sudah kamu kenal: &lt; diganti jadi <. Yang berbahaya adalah external entity, yang didefinisikan di DTD (Document Type Definition) dan menunjuk ke sebuah file atau URL:

<!ENTITY xxe SYSTEM "file:///etc/passwd">

Jadi &xxe; bukan lagi teks biasa: dia jadi pintu ke file di server.

Payload klasik: baca file

Di Lab, kirim dokumen ini ke endpoint yang mem-parsing XML:

<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<foo>&xxe;</foo>

Dengan parser yang masih memproses external entity, langkahnya begini:

  1. Parser membaca <!DOCTYPE> dan mendefinisikan entity xxe yang menunjuk ke file:///etc/passwd.
  2. Waktu sampai &xxe;, parser menggantinya dengan isi file di path itu.
  3. Hasilnya masuk ke response, jadi isi file server bocor ke penyerang.

Tidak ada kode penyerang yang jalan di sini. Yang terjadi: parser menuruti alamat file yang ditunjuk entity, lalu menaruhnya di jawaban. Bagian file:///etc/passwd itulah yang berubah dari sekadar teks jadi sebuah path yang dibaca server.

Varian lain

Cara memperbaiki

Intinya satu: matikan pemrosesan DTD/external entity. Hampir semua aplikasi web tidak butuh DTD. Itu jawaban tebakannya: fitur yang membuka pintu XXE adalah external entities.

// PHP: jangan tambah flag berbahaya. Default PHP 8+ sudah aman.
// Di PHP lama, matikan pemuat entitas eksternal secara eksplisit:
libxml_disable_entity_loader(true);

Latihan: deteksi pola XXE

Di latihan, kamu menulis isXmlDangerous(xml) yang mengembalikan true kalau sebuah string XML kemungkinan payload XXE. Yang paling menentukan adalah adanya DTD inline (<!DOCTYPE) atau deklarasi entity (<!ENTITY), karena tanpa DTD tidak ada tempat mendefinisikan external entity. Cek secara case-insensitive, karena <!doctype dan <!DOCTYPE sama bahayanya. Contoh: <note><to>Budi</to></note> mengembalikan false, sedangkan <!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]> mengembalikan true.

⚠️ Jebakan yang sering ketemu

TL;DR: XXE terjadi saat XML parser memproses external entities, yang didefinisikan di DTD lewat <!ENTITY xxe SYSTEM "...">. Entity itu menunjuk ke file (bocor isi file), URL internal (jadi SSRF), atau mengembang eksponensial (billion laughs, DoS). Perbaikannya: matikan DTD/external entity. Di PHP lama pakai libxml_disable_entity_loader(true), di Python pakai defusedxml, dan kalau bisa ganti ke JSON. Deteksi dini: tandai XML yang mengandung <!DOCTYPE atau <!ENTITY, case-insensitive.

Yang akan kamu pelajari