XML Entity Expansion in .NET
Vulnerable example
The following C# snippet parses the content of an XML file using the XmlDocument
class:
XmlDocument document = new XmlDocument();
document.XmlResolver = new XmlUrlResolver();
document.Load(model.MyFileInput.OpenReadStream());
Notice that a non-default resolver (XmlUrlResolver
) is used to resolve external entities during the parsing. The snippet parses XML data in an unsafe way and can be exploited to inject a specially forged XML to disclose the /etc/passwd
system file referring its path as an external entity, for example:
<!DOCTYPE d [<!ENTITY e SYSTEM "/etc/passwd">]><t>&e;</t>
Prevention
XMLDocument
In versions preceding .NET version 4.6, XMLDocument
sets the XmlResolver
property to URLResolver
, allowing DTD parsing that could lead to an XML Entity Expansion attack. To prohibit this, the XmlResolver
should be explicitly set to null
.
Starting from .NET version 4.6, XmlDocument
’s XmlResolver
is set to null, defaulting to a safe configuration. When parsing external entities is not needed, it is advisable to use the default behavior, i.e., by omitting the line:
// Vulnerable setting
document.XmlResolver = new XmlUrlResolver();
If instead the parsing of external entities is required by the semantics of the web application, it is possible to use an instance of XmlSecureResolver
in place of XmlUrlResolver
as it provides a means to fine-tune the allowed external entities and their loading behavior.
XMLReader
In versions preceding .NET version 4.0, the XMLReader
’s ProhibitDtd
property is used to determine if a DTD will be parsed. It is set to True
by default, which throws an exception if a DTD is identified.
Starting from .NET version 4.0, it is possible to configure the DtdProcessing
property to Ignore
to ignore the DTD without throwing an exception.
XmlTextReader
In versions preceding .NET version 4.0, the XmlTextReader
’s ProhibitDtd
property is used to determine if a DTD will be parsed. It is set to False
by default, allowing dangerous parsing of DTD documents.
Starting from .NET version 4.0, it is possible to configure the DtdProcessing
property to Prohibit
to throw an exception if a DTD is identified or Ignore
to ignore the DTD without throwing an exception.
References
OWASP - XML External Entity (XXE) Processing OWASP - XML External Entity Prevention Cheat Sheet GitHub - .NET XXE Learning Tests