== How to fix it in lxml

=== Code examples

include::../../common/fix/code-rationale.adoc[]

==== Noncompliant code example

When parsing XML:

[source,python,diff-id=1,diff-type=noncompliant]
----
from lxml import etree

parser = etree.XMLParser() # Noncompliant
tree = etree.parse('xxe.xml', parser) 
root = tree1.getroot()
----

When validating XML:

[source,python,diff-id=2,diff-type=noncompliant]
----
from lxml import etree

parser = etree.XMLParser(resolve_entities=True) # Noncompliant
treexsd = etree.parse('xxe.xsd', parser) 
rootxsd = treexsd.getroot()
schema = etree.XMLSchema(rootxsd)
----

When transforming XML:

[source,python,diff-id=3,diff-type=noncompliant]
----
from lxml import etree

ac = etree.XSLTAccessControl(read_network=True, write_network=False)  # Noncompliant
transform = etree.XSLT(rootxsl, access_control=ac)
----

==== Compliant solution

When parsing XML, disable entity resolving and network access:

[source,python,diff-id=1,diff-type=compliant]
----
from lxml import etree

parser = etree.XMLParser(resolve_entities=False, no_network=True)
tree1 = etree.parse('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,diff-id=2,diff-type=compliant]
----
from lxml import etree

parser = etree.XMLParser(resolve_entities=False)
treexsd = etree.parse('xxe.xsd', parser) 
rootxsd = treexsd.getroot()
schema = etree.XMLSchema(rootxsd)
----

When transforming XML, disable access to network and file system:

[source,python,diff-id=3,diff-type=compliant]
----
from lxml import etree

parser = etree.XMLParser(resolve_entities=False)
treexsl = etree.parse('xxe.xsl', parser)  
rootxsl = treexsl.getroot()

ac = etree.XSLTAccessControl.DENY_ALL
transform = etree.XSLT(rootxsl, access_control=ac)
----

=== How does this work?

include::../../common/fix/xxe.adoc[]
