CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-defusedxml

XML bomb protection for Python stdlib modules

Pending
Overview
Eval results
Files

exceptions.mddocs/

Exception Handling

DefusedXML provides a comprehensive exception hierarchy for handling XML security violations and library-specific errors. All exceptions inherit from the base DefusedXmlException class, which itself inherits from ValueError.

Capabilities

Base Exception

Base exception class for all defusedxml security violations and errors.

class DefusedXmlException(ValueError):
    """
    Base exception for all defusedxml security violations and errors.
    
    Inherits from ValueError to maintain compatibility with standard XML
    processing error handling patterns.
    """
    
    def __repr__(self):
        """Return string representation of the exception"""

DTD Processing Violations

Exception raised when document type definition (DTD) processing is attempted but forbidden by security settings.

class DTDForbidden(DefusedXmlException):
    """
    Raised when DTD processing is attempted but forbidden.
    
    DTD processing can be exploited for external entity attacks and
    DTD processing attacks that can access local files or make 
    network requests.
    
    Attributes:
        name (str): The name of the DTD
        sysid (str): System identifier of the DTD
        pubid (str): Public identifier of the DTD
    """
    
    def __init__(self, name, sysid, pubid):
        """
        Initialize DTDForbidden exception.
        
        Args:
            name (str): The name of the DTD
            sysid (str): System identifier of the DTD  
            pubid (str): Public identifier of the DTD
        """
    
    def __str__(self):
        """Return formatted string representation"""

Usage Example:

import defusedxml.ElementTree as ET

xml_with_dtd = '''<?xml version="1.0"?>
<!DOCTYPE root SYSTEM "http://example.com/malicious.dtd">
<root>content</root>'''

try:
    # This will raise DTDForbidden with default settings
    root = ET.fromstring(xml_with_dtd, forbid_dtd=True)
except defusedxml.DTDForbidden as e:
    print(f"DTD processing blocked: {e}")
    print(f"DTD name: {e.name}")
    print(f"System ID: {e.sysid}")
    print(f"Public ID: {e.pubid}")

Entity Processing Violations

Exception raised when entity processing is attempted but forbidden by security settings.

class EntitiesForbidden(DefusedXmlException):
    """
    Raised when entity processing is attempted but forbidden.
    
    Entity processing can be exploited for billion laughs attacks,
    quadratic blowup attacks, and external entity attacks that can
    consume excessive memory or access external resources.
    
    Attributes:
        name (str): The name of the entity
        value (str): The value of the entity (may be None)
        base (str): Base URI for resolving relative references
        sysid (str): System identifier of the entity
        pubid (str): Public identifier of the entity  
        notation_name (str): Notation name for unparsed entities
    """
    
    def __init__(self, name, value, base, sysid, pubid, notation_name):
        """
        Initialize EntitiesForbidden exception.
        
        Args:
            name (str): The name of the entity
            value (str): The value of the entity (may be None)
            base (str): Base URI for resolving relative references
            sysid (str): System identifier of the entity
            pubid (str): Public identifier of the entity
            notation_name (str): Notation name for unparsed entities
        """
    
    def __str__(self):
        """Return formatted string representation"""

Usage Example:

import defusedxml.ElementTree as ET

xml_with_entities = '''<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
]>
<root>&lol2;</root>'''

try:
    # This will raise EntitiesForbidden with default settings
    root = ET.fromstring(xml_with_entities)
except defusedxml.EntitiesForbidden as e:
    print(f"Entity processing blocked: {e}")
    print(f"Entity name: {e.name}")
    print(f"Entity value: {e.value}")

External Reference Violations

Exception raised when external reference processing is attempted but forbidden by security settings.

class ExternalReferenceForbidden(DefusedXmlException):
    """
    Raised when external reference processing is attempted but forbidden.
    
    External references can be exploited for server-side request forgery
    (SSRF) attacks, local file access, and network reconnaissance by
    forcing the parser to make HTTP requests or access local files.
    
    Attributes:
        context (str): Context information about the reference
        base (str): Base URI for resolving relative references
        sysid (str): System identifier of the external reference
        pubid (str): Public identifier of the external reference
    """
    
    def __init__(self, context, base, sysid, pubid):
        """
        Initialize ExternalReferenceForbidden exception.
        
        Args:
            context (str): Context information about the reference
            base (str): Base URI for resolving relative references  
            sysid (str): System identifier of the external reference
            pubid (str): Public identifier of the external reference
        """
    
    def __str__(self):
        """Return formatted string representation"""

Usage Example:

import defusedxml.ElementTree as ET

xml_with_external = '''<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY external SYSTEM "file:///etc/passwd">
]>
<root>&external;</root>'''

try:
    # This will raise ExternalReferenceForbidden with default settings
    root = ET.fromstring(xml_with_external)
except defusedxml.ExternalReferenceForbidden as e:
    print(f"External reference blocked: {e}")
    print(f"System ID: {e.sysid}")
    print(f"Public ID: {e.pubid}")

Unsupported Operations

Exception raised when an operation is not supported by the defused implementation.

class NotSupportedError(DefusedXmlException):
    """
    Raised when an operation is not supported by the defused implementation.
    
    Some XML processing features are intentionally not supported in defused
    implementations to maintain security, or may not be available in certain
    configurations or library versions.
    """

Usage Example:

import defusedxml.lxml as lxml_defused

try:
    # iterparse is not supported in defused lxml
    parser = lxml_defused.iterparse('document.xml')
except defusedxml.NotSupportedError as e:
    print(f"Operation not supported: {e}")

Exception Hierarchy

ValueError
└── DefusedXmlException
    ├── DTDForbidden
    ├── EntitiesForbidden  
    ├── ExternalReferenceForbidden
    └── NotSupportedError

Common Exception Handling Patterns

Comprehensive Exception Handling

import defusedxml.ElementTree as ET
import defusedxml

def safe_parse_xml(xml_content):
    """Safely parse XML with comprehensive error handling."""
    try:
        return ET.fromstring(xml_content)
    except ET.ParseError as e:
        print(f"XML syntax error: {e}")
        return None
    except defusedxml.DTDForbidden as e:
        print(f"DTD processing forbidden: {e}")
        return None
    except defusedxml.EntitiesForbidden as e:
        print(f"Entity processing forbidden: {e}")
        return None
    except defusedxml.ExternalReferenceForbidden as e:
        print(f"External reference forbidden: {e}")
        return None
    except defusedxml.DefusedXmlException as e:
        print(f"Other defusedxml error: {e}")
        return None

Selective Exception Handling

import defusedxml.ElementTree as ET
import defusedxml

def parse_with_fallback(xml_content, allow_dtd=False):
    """Parse XML with security fallbacks."""
    try:
        return ET.fromstring(xml_content, forbid_dtd=not allow_dtd)
    except defusedxml.DTDForbidden:
        if not allow_dtd:
            # Retry with DTD allowed
            return ET.fromstring(xml_content, forbid_dtd=False)
        raise
    except (defusedxml.EntitiesForbidden, defusedxml.ExternalReferenceForbidden):
        # These are always security risks, don't retry
        raise

Install with Tessl CLI

npx tessl i tessl/pypi-defusedxml

docs

dom.md

elementtree.md

exceptions.md

index.md

sax.md

stdlib-patching.md

xmlrpc.md

tile.json