91 lines
2.7 KiB
Plaintext
91 lines
2.7 KiB
Plaintext
![]() |
include::../description.adoc[]
|
||
|
|
||
|
== Noncompliant Code Example
|
||
|
|
||
|
https://lxml.de/[lxml] module:
|
||
|
|
||
|
* When parsing XML:
|
||
|
|
||
|
----
|
||
|
parser = etree.XMLParser() # Noncompliant: by default resolve_entities is set to true
|
||
|
tree1 = etree.parse('ressources/xxe.xml', parser)
|
||
|
root1 = tree1.getroot()
|
||
|
|
||
|
parser = etree.XMLParser(resolve_entities=True) # Noncompliant
|
||
|
tree1 = etree.parse('ressources/xxe.xml', parser)
|
||
|
root1 = tree1.getroot()
|
||
|
----
|
||
|
|
||
|
* When validating XML:
|
||
|
|
||
|
----
|
||
|
parser = etree.XMLParser(resolve_entities=True) # Noncompliant
|
||
|
treexsd = etree.parse('ressources/xxe.xsd', parser)
|
||
|
rootxsd = treexsd.getroot()
|
||
|
schema = etree.XMLSchema(rootxsd)
|
||
|
----
|
||
|
|
||
|
* When transforming XML:
|
||
|
|
||
|
----
|
||
|
ac = etree.XSLTAccessControl(read_network=True, write_network=False) # Noncompliant, read_network is set to true/network access is authorized
|
||
|
transform = etree.XSLT(rootxsl, access_control=ac)
|
||
|
----
|
||
|
|
||
|
https://docs.python.org/3/library/xml.sax.html[xml.sax] module:
|
||
|
|
||
|
----
|
||
|
parser = xml.sax.make_parser()
|
||
|
myHandler = MyHandler()
|
||
|
parser.setContentHandler(myHandler)
|
||
|
|
||
|
parser.setFeature(feature_external_ges, True) # Noncompliant
|
||
|
parser.parse("ressources/xxe.xml")
|
||
|
----
|
||
|
|
||
|
== Compliant Solution
|
||
|
|
||
|
https://lxml.de/[lxml] module:
|
||
|
|
||
|
* When parsing XML, disable _resolve_entities_ and _network access_:
|
||
|
|
||
|
----
|
||
|
parser = etree.XMLParser(resolve_entities=False, no_network=True) # Compliant
|
||
|
tree1 = etree.parse('ressources/xxe.xml', parser)
|
||
|
root1 = tree1.getroot()
|
||
|
----
|
||
|
|
||
|
* When validating XML (note that network access https://bugs.launchpad.net/lxml/+bug/1234114[cannot be completely disabled] when calling XMLSchema):
|
||
|
|
||
|
----
|
||
|
parser = etree.XMLParser(resolve_entities=False) # Compliant: by default no_network is set to true
|
||
|
treexsd = etree.parse('ressources/xxe.xsd', parser)
|
||
|
rootxsd = treexsd.getroot()
|
||
|
schema = etree.XMLSchema(rootxsd) # Compliant
|
||
|
----
|
||
|
|
||
|
* When transforming XML, disable access to network and file system:
|
||
|
|
||
|
----
|
||
|
parser = etree.XMLParser(resolve_entities=False) # Compliant
|
||
|
treexsl = etree.parse('ressources/xxe.xsl', parser)
|
||
|
rootxsl = treexsl.getroot()
|
||
|
|
||
|
ac = etree.XSLTAccessControl.DENY_ALL # Compliant
|
||
|
transform = etree.XSLT(rootxsl, access_control=ac) # Compliant
|
||
|
----
|
||
|
|
||
|
To prevent xxe attacks with https://docs.python.org/3/library/xml.sax.html[xml.sax] module (for https://docs.python.org/3/library/xml.html#xml-vulnerabilities[other security reasons] than XXE, xml.sax is not recommended):
|
||
|
|
||
|
----
|
||
|
parser = xml.sax.make_parser()
|
||
|
myHandler = MyHandler()
|
||
|
parser.setContentHandler(myHandler)
|
||
|
parser.parse("ressources/xxe.xml") # Compliant: in version 3.7.1: The SAX parser no longer processes general external entities by default
|
||
|
|
||
|
parser.setFeature(feature_external_ges, False) # Compliant
|
||
|
parser.parse("ressources/xxe.xml")
|
||
|
----
|
||
|
|
||
|
include::../see.adoc[]
|