XML bomb protection for Python stdlib modules
npx @tessl/cli install tessl/pypi-defusedxml@0.7.0A comprehensive Python library that provides XML bomb protection for Python's standard library XML processing modules. DefusedXML offers secure alternatives to xml.etree.ElementTree, xml.sax, xml.dom.minidom, xml.dom.pulldom, and xml.parsers.expat by disabling dangerous features like external entity processing, DTD processing, and entity expansion that can be exploited for billion laughs attacks, quadratic blowup attacks, and external entity attacks.
pip install defusedxmlimport defusedxml
from defusedxml import DefusedXmlException, DTDForbidden, EntitiesForbidden, ExternalReferenceForbidden, NotSupportedErrorDrop-in replacements for stdlib modules:
import defusedxml.ElementTree as ET # instead of xml.etree.ElementTree
import defusedxml.sax as sax # instead of xml.sax
import defusedxml.minidom as minidom # instead of xml.dom.minidom
import defusedxml.pulldom as pulldom # instead of xml.dom.pulldomDeprecated modules (avoid in new code):
import defusedxml.cElementTree as cET # DEPRECATED: use defusedxml.ElementTree instead
import defusedxml.lxml as lxml_defused # DEPRECATED: no longer supported, will be removedimport defusedxml.ElementTree as ET
# Parse XML safely with default security restrictions
try:
# Parse from file
tree = ET.parse('document.xml')
root = tree.getroot()
# Parse from string
xml_string = '<root><item>value</item></root>'
root = ET.fromstring(xml_string)
# Access elements normally
for item in root.findall('item'):
print(item.text)
except ET.ParseError as e:
print(f"XML parsing error: {e}")
except defusedxml.DTDForbidden as e:
print(f"DTD processing forbidden: {e}")
except defusedxml.EntitiesForbidden as e:
print(f"Entity processing forbidden: {e}")DefusedXML provides secure wrappers around Python's standard XML processing modules:
The security model prevents XML-based attacks by:
Core exception classes for handling XML security violations and library-specific errors.
class DefusedXmlException(ValueError):
"""Base exception for all defusedxml security violations"""
class DTDForbidden(DefusedXmlException):
"""Raised when DTD processing is attempted but forbidden"""
class EntitiesForbidden(DefusedXmlException):
"""Raised when entity processing is attempted but forbidden"""
class ExternalReferenceForbidden(DefusedXmlException):
"""Raised when external reference processing is attempted but forbidden"""
class NotSupportedError(DefusedXmlException):
"""Raised when an operation is not supported by the defused implementation"""Secure ElementTree-based XML parsing with configurable security restrictions, providing drop-in replacement for xml.etree.ElementTree with comprehensive protection against XML attacks.
def parse(source, parser=None, forbid_dtd=False, forbid_entities=True, forbid_external=True): ...
def iterparse(source, events=None, parser=None, forbid_dtd=False, forbid_entities=True, forbid_external=True): ...
def fromstring(text, forbid_dtd=False, forbid_entities=True, forbid_external=True): ...
def XML(text, forbid_dtd=False, forbid_entities=True, forbid_external=True): ...
class DefusedXMLParser: ...Secure SAX-based XML parsing with event-driven processing and configurable security restrictions, providing drop-in replacement for xml.sax with protection against XML attacks.
def parse(source, handler, errorHandler=None, forbid_dtd=False, forbid_entities=True, forbid_external=True): ...
def parseString(string, handler, errorHandler=None, forbid_dtd=False, forbid_entities=True, forbid_external=True): ...
def make_parser(parser_list=[]): ...
class DefusedExpatParser: ...Secure DOM-based XML parsing that builds complete document object models with configurable security restrictions, providing drop-in replacements for xml.dom.minidom and xml.dom.pulldom.
# minidom functions
def parse(file, parser=None, bufsize=None, forbid_dtd=False, forbid_entities=True, forbid_external=True): ...
def parseString(string, parser=None, forbid_dtd=False, forbid_entities=True, forbid_external=True): ...
# pulldom functions
def parse(stream_or_string, parser=None, bufsize=None, forbid_dtd=False, forbid_entities=True, forbid_external=True): ...
def parseString(string, parser=None, forbid_dtd=False, forbid_entities=True, forbid_external=True): ...Secure XML-RPC client and server protection with gzip bomb prevention, providing defused parsers and decompression limits for XML-RPC communications.
def monkey_patch(): ...
def unmonkey_patch(): ...
def defused_gzip_decode(data, limit=None): ...
class DefusedExpatParser: ...
class DefusedGzipDecodedResponse: ...Experimental system-wide XML protection by monkey-patching all standard library XML modules with defused alternatives.
def defuse_stdlib(): ...All parsing functions accept these security configuration parameters:
forbid_dtd (bool, default: False): Forbid DTD processing to prevent DTD-based attacksforbid_entities (bool, default: True): Forbid entity expansion to prevent billion laughs attacksforbid_external (bool, default: True): Forbid external references to prevent SSRF and local file accessUse default security settings for maximum protection:
import defusedxml.ElementTree as ET
root = ET.fromstring(xml_string) # Uses secure defaultsAdjust security parameters based on trust level:
# Allow DTDs but keep other protections
root = ET.fromstring(xml_string, forbid_dtd=False)
# Allow entities for trusted content
root = ET.fromstring(trusted_xml, forbid_entities=False)Handle security violations gracefully:
try:
root = ET.fromstring(untrusted_xml)
except defusedxml.DTDForbidden:
# Handle DTD processing attempt
except defusedxml.EntitiesForbidden:
# Handle entity expansion attempt
except defusedxml.ExternalReferenceForbidden:
# Handle external reference attempt