== Why is this an issue?

include::../description.adoc[]

=== Noncompliant code example

https://lxml.de/[lxml] module:

* When parsing XML:

[source,python]
----
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:

[source,python]
----
parser = etree.XMLParser(resolve_entities=True) # Noncompliant
treexsd = etree.parse('ressources/xxe.xsd', parser) 
rootxsd = treexsd.getroot()
schema = etree.XMLSchema(rootxsd) 
----

* When transforming XML:

[source,python]
----
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:

[source,python]
----
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_:

[source,python]
----
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):

[source,python]
----
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:

[source,python]
----
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):

[source,python]
----
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[]

ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

include::../message.adoc[]

include::highlighting.adoc[]

'''
== Comments And Links
(visible only on this page)

include::../comments-and-links.adoc[]
endif::env-github,rspecator-view[]
