0
# Exception Handling
1
2
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.
3
4
## Capabilities
5
6
### Base Exception
7
8
Base exception class for all defusedxml security violations and errors.
9
10
```python { .api }
11
class DefusedXmlException(ValueError):
12
"""
13
Base exception for all defusedxml security violations and errors.
14
15
Inherits from ValueError to maintain compatibility with standard XML
16
processing error handling patterns.
17
"""
18
19
def __repr__(self):
20
"""Return string representation of the exception"""
21
```
22
23
### DTD Processing Violations
24
25
Exception raised when document type definition (DTD) processing is attempted but forbidden by security settings.
26
27
```python { .api }
28
class DTDForbidden(DefusedXmlException):
29
"""
30
Raised when DTD processing is attempted but forbidden.
31
32
DTD processing can be exploited for external entity attacks and
33
DTD processing attacks that can access local files or make
34
network requests.
35
36
Attributes:
37
name (str): The name of the DTD
38
sysid (str): System identifier of the DTD
39
pubid (str): Public identifier of the DTD
40
"""
41
42
def __init__(self, name, sysid, pubid):
43
"""
44
Initialize DTDForbidden exception.
45
46
Args:
47
name (str): The name of the DTD
48
sysid (str): System identifier of the DTD
49
pubid (str): Public identifier of the DTD
50
"""
51
52
def __str__(self):
53
"""Return formatted string representation"""
54
```
55
56
**Usage Example:**
57
58
```python
59
import defusedxml.ElementTree as ET
60
61
xml_with_dtd = '''<?xml version="1.0"?>
62
<!DOCTYPE root SYSTEM "http://example.com/malicious.dtd">
63
<root>content</root>'''
64
65
try:
66
# This will raise DTDForbidden with default settings
67
root = ET.fromstring(xml_with_dtd, forbid_dtd=True)
68
except defusedxml.DTDForbidden as e:
69
print(f"DTD processing blocked: {e}")
70
print(f"DTD name: {e.name}")
71
print(f"System ID: {e.sysid}")
72
print(f"Public ID: {e.pubid}")
73
```
74
75
### Entity Processing Violations
76
77
Exception raised when entity processing is attempted but forbidden by security settings.
78
79
```python { .api }
80
class EntitiesForbidden(DefusedXmlException):
81
"""
82
Raised when entity processing is attempted but forbidden.
83
84
Entity processing can be exploited for billion laughs attacks,
85
quadratic blowup attacks, and external entity attacks that can
86
consume excessive memory or access external resources.
87
88
Attributes:
89
name (str): The name of the entity
90
value (str): The value of the entity (may be None)
91
base (str): Base URI for resolving relative references
92
sysid (str): System identifier of the entity
93
pubid (str): Public identifier of the entity
94
notation_name (str): Notation name for unparsed entities
95
"""
96
97
def __init__(self, name, value, base, sysid, pubid, notation_name):
98
"""
99
Initialize EntitiesForbidden exception.
100
101
Args:
102
name (str): The name of the entity
103
value (str): The value of the entity (may be None)
104
base (str): Base URI for resolving relative references
105
sysid (str): System identifier of the entity
106
pubid (str): Public identifier of the entity
107
notation_name (str): Notation name for unparsed entities
108
"""
109
110
def __str__(self):
111
"""Return formatted string representation"""
112
```
113
114
**Usage Example:**
115
116
```python
117
import defusedxml.ElementTree as ET
118
119
xml_with_entities = '''<?xml version="1.0"?>
120
<!DOCTYPE root [
121
<!ENTITY lol "lol">
122
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
123
]>
124
<root>&lol2;</root>'''
125
126
try:
127
# This will raise EntitiesForbidden with default settings
128
root = ET.fromstring(xml_with_entities)
129
except defusedxml.EntitiesForbidden as e:
130
print(f"Entity processing blocked: {e}")
131
print(f"Entity name: {e.name}")
132
print(f"Entity value: {e.value}")
133
```
134
135
### External Reference Violations
136
137
Exception raised when external reference processing is attempted but forbidden by security settings.
138
139
```python { .api }
140
class ExternalReferenceForbidden(DefusedXmlException):
141
"""
142
Raised when external reference processing is attempted but forbidden.
143
144
External references can be exploited for server-side request forgery
145
(SSRF) attacks, local file access, and network reconnaissance by
146
forcing the parser to make HTTP requests or access local files.
147
148
Attributes:
149
context (str): Context information about the reference
150
base (str): Base URI for resolving relative references
151
sysid (str): System identifier of the external reference
152
pubid (str): Public identifier of the external reference
153
"""
154
155
def __init__(self, context, base, sysid, pubid):
156
"""
157
Initialize ExternalReferenceForbidden exception.
158
159
Args:
160
context (str): Context information about the reference
161
base (str): Base URI for resolving relative references
162
sysid (str): System identifier of the external reference
163
pubid (str): Public identifier of the external reference
164
"""
165
166
def __str__(self):
167
"""Return formatted string representation"""
168
```
169
170
**Usage Example:**
171
172
```python
173
import defusedxml.ElementTree as ET
174
175
xml_with_external = '''<?xml version="1.0"?>
176
<!DOCTYPE root [
177
<!ENTITY external SYSTEM "file:///etc/passwd">
178
]>
179
<root>&external;</root>'''
180
181
try:
182
# This will raise ExternalReferenceForbidden with default settings
183
root = ET.fromstring(xml_with_external)
184
except defusedxml.ExternalReferenceForbidden as e:
185
print(f"External reference blocked: {e}")
186
print(f"System ID: {e.sysid}")
187
print(f"Public ID: {e.pubid}")
188
```
189
190
### Unsupported Operations
191
192
Exception raised when an operation is not supported by the defused implementation.
193
194
```python { .api }
195
class NotSupportedError(DefusedXmlException):
196
"""
197
Raised when an operation is not supported by the defused implementation.
198
199
Some XML processing features are intentionally not supported in defused
200
implementations to maintain security, or may not be available in certain
201
configurations or library versions.
202
"""
203
```
204
205
**Usage Example:**
206
207
```python
208
import defusedxml.lxml as lxml_defused
209
210
try:
211
# iterparse is not supported in defused lxml
212
parser = lxml_defused.iterparse('document.xml')
213
except defusedxml.NotSupportedError as e:
214
print(f"Operation not supported: {e}")
215
```
216
217
## Exception Hierarchy
218
219
```
220
ValueError
221
└── DefusedXmlException
222
├── DTDForbidden
223
├── EntitiesForbidden
224
├── ExternalReferenceForbidden
225
└── NotSupportedError
226
```
227
228
## Common Exception Handling Patterns
229
230
### Comprehensive Exception Handling
231
232
```python
233
import defusedxml.ElementTree as ET
234
import defusedxml
235
236
def safe_parse_xml(xml_content):
237
"""Safely parse XML with comprehensive error handling."""
238
try:
239
return ET.fromstring(xml_content)
240
except ET.ParseError as e:
241
print(f"XML syntax error: {e}")
242
return None
243
except defusedxml.DTDForbidden as e:
244
print(f"DTD processing forbidden: {e}")
245
return None
246
except defusedxml.EntitiesForbidden as e:
247
print(f"Entity processing forbidden: {e}")
248
return None
249
except defusedxml.ExternalReferenceForbidden as e:
250
print(f"External reference forbidden: {e}")
251
return None
252
except defusedxml.DefusedXmlException as e:
253
print(f"Other defusedxml error: {e}")
254
return None
255
```
256
257
### Selective Exception Handling
258
259
```python
260
import defusedxml.ElementTree as ET
261
import defusedxml
262
263
def parse_with_fallback(xml_content, allow_dtd=False):
264
"""Parse XML with security fallbacks."""
265
try:
266
return ET.fromstring(xml_content, forbid_dtd=not allow_dtd)
267
except defusedxml.DTDForbidden:
268
if not allow_dtd:
269
# Retry with DTD allowed
270
return ET.fromstring(xml_content, forbid_dtd=False)
271
raise
272
except (defusedxml.EntitiesForbidden, defusedxml.ExternalReferenceForbidden):
273
# These are always security risks, don't retry
274
raise
275
```