flawopen.com/Entitas eksternal XML (XXE)/Keamanan parser XML Python
Apakah xml.etree.ElementTree Python aman dari XXE?
Untuk XXE klasik yang membaca berkas atau memakai jaringan, parser Expat bawaan Python secara default tidak mengakses berkas lokal atau membuka koneksi jaringan. Namun, tidak semua pemrosesan XML aman: Expat sebelum 2.7.2 dapat terkena DoS lewat ekspansi entitas dan token besar. Default lxml juga berubah antarversi. Tetapkan versi dan opsi parser secara eksplisit, atau gunakan defusedxml untuk XML tak tepercaya.
BERISIKO — versi dan opsi mengubah paparan
- XXE (CWE-611):
- Parser memproses entitas eksternal dari XML kendali penyerang, yang dapat membaca berkas lokal atau membuat permintaan dari server.
- DoS ekspansi entitas:
- Referensi bertingkat atau berulang menghabiskan CPU atau memori secara berlebihan saat diperluas.
- Expat:
- Parser C untuk modul XML bawaan Python; cek versi runtime melalui
pyexpat.EXPAT_VERSION. - DTD:
- Deklarasi tipe dokumen dapat menentukan entitas dan, bergantung pengaturan parser, meminta sumber eksternal.
XML tak tepercaya mencapai parser
Unggahan, SVG, pesan SAML, atau data integrasi melewati batas kepercayaan ke API XML.
Implementasi dan opsi menentukan perilaku
Pustaka standar memakai Expat; lxml memakai libxml2. Versi, resolusi eksternal, ekspansi, dan flag menentukan perilaku yang mungkin.
Resolusi atau ekspansi menimbulkan dampak
Jika resolusi eksternal aktif, entitas dapat meminta konten lokal atau jarak jauh. Ekspansi rentan dan token besar juga dapat menghabiskan sumber daya.
Hak proses membatasi dampak
Hak berkas dan egress jaringan membatasi dampak XXE; batas masukan, parser terbaru, flag aman, dan isolasi mengurangi paparan.
Panduan keamanan Python saat ini menyatakan Expat secara default tidak mengakses berkas lokal atau membuat koneksi jaringan. Namun, versi sebelum 2.7.2 dapat rentan terhadap billion laughs, quadratic blowup, token besar, atau penggunaan memori yang berlebihan. Periksa pyexpat.EXPAT_VERSION karena Python dapat memakai Expat bawaan atau sistem. Ini risiko kehabisan sumber daya berdasarkan versi, bukan bukti bahwa ElementTree saat ini memproses entitas eksternal.
# Standard-library external access is off by default, # but old Expat builds have resource-exhaustion risks. import xml.etree.ElementTree as ET from xml.parsers import expat print(expat.EXPAT_VERSION) # inspect the runtime parser root = ET.fromstring(untrusted_xml) # lxml before 5.0 defaulted resolve_entities=True. # Explicit unsafe settings illustrate the risky boundary. from lxml import etree parser = etree.XMLParser(resolve_entities=True, load_dtd=True) root = etree.fromstring(untrusted_xml, parser)
from defusedxml.ElementTree import fromstring
# Reject DTD declarations when the format does not require them.
root = fromstring(untrusted_xml, forbid_dtd=True)
# If lxml is required, set its security options explicitly.
from lxml import etree
parser = etree.XMLParser(
resolve_entities=False,
no_network=True,
load_dtd=False,
huge_tree=False,
)
root = etree.fromstring(untrusted_xml, parser)
# Do not run XInclude on untrusted trees without a restricted loader.
Pilih setelan aman untuk parser yang benar-benar digunakan
Pada defusedxml.ElementTree, deklarasi entitas dan referensi eksternal dilarang secara default; tambahkan forbid_dtd=True jika format tidak membutuhkan DTD. Untuk lxml, tetapkan resolve_entities=False, load_dtd=False, no_network=True, dan huge_tree=False secara eksplisit. Versi saat ini hanya memproses entitas internal secara default; sebelum lxml 5.0, resolusi aktif. Jangan jalankan XInclude pada tree tak tepercaya tanpa loader terbatas. Batasi ukuran sebelum dekompresi dan parsing.
- ✓Inventarisasi setiap titik masuk dan parser XML: ElementTree/Expat, lxml/libxml2, SAX/DOM, SVG, SAML, impor arsip, dan langkah XInclude berikutnya.
- ✓Gunakan Python yang didukung dengan Expat 2.7.2 atau lebih baru bila tersedia; verifikasi versi aktif menggunakan
pyexpat.EXPAT_VERSION. - ✓Untuk XML tak tepercaya, gunakan
defusedxml; tolak DTD denganforbid_dtd=Truejika skema tidak memerlukannya. - ✓Jika memakai lxml, pin versi terpelihara dan nonaktifkan resolusi entitas, pemuatan DTD, jaringan, dan huge-tree secara eksplisit; jangan andalkan default yang berubah.
- ✓Batasi ukuran terkompresi dan setelah dekompresi, isolasi parsing bila perlu, dan uji fixture DTD/entity yang jinak di CI tanpa permintaan eksternal.
Mengapa default parser perlu ditinjau sesuai versi
“XML Python” bukan satu konfigurasi parser. Pustaka standar memakai Expat bawaan atau sistem bergantung build interpreter. lxml membungkus libxml2 dan mengubah default resolusi entitas pada versi 5.0; wrapper dan opsi eksplisit dapat mengubah perilaku lagi. Catat versi Python, Expat, lxml, libxml2 dan tetapkan flag keamanan pada tiap jalur masukan tak tepercaya.
Pertanyaan umum
Tidak. Python menyatakan Expat secara default tidak mengakses berkas lokal atau jaringan. Cek versinya dan bedakan XXE file-read dari risiko kehabisan sumber daya pada parser lama.
Jangan menyamaratakan semua versi. XMLParser saat ini hanya memproses entitas internal, tidak memuat DTD dan tidak memakai jaringan secara default. lxml 5.0 mengubah resolve_entities dari True ke internal. Tetapkan opsi dan periksa wrapper.
Tidak. Entitas dan referensi eksternal dilarang, tetapi forbid_dtd bernilai False. Tetapkan True jika format tidak membutuhkan DTD.
Tidak. Batasi masukan terkompresi dan hasil dekompresi, perbarui parser, hindari huge_tree, dan jangan proses XInclude tak tepercaya dengan loader tanpa batas.