Skip to main content

XML injection (XXE)

Need

Prevention of XML injection attacks

Context

  • Usage of C# for building robust and scalable applications
  • Usage of System.Xml for XML data processing and manipulation
  • Usage of System.Xml.Linq for XML document manipulation and querying

Description

Non compliant code

using System.Xml;
using System.Xml.Linq;

public class XMLController : Controller
{
[HttpPost]
public IActionResult Post([FromBody] string xmlData)
{
var xmlReaderSettings = new XmlReaderSettings();
var xmlReader = XmlReader.Create(new StringReader(xmlData), xmlReaderSettings);
var xmlDoc = XDocument.Load(xmlReader);

// Process XML data...

return Ok();
}
}

The above code is an ASP.NET Core Controller that accepts XML data in a POST request. The XML data is read from the request body and then loaded into an XDocument using an XmlReader.

The vulnerability lies in the fact that the XmlReaderSettings object is not properly configured to prevent XML External Entity (XXE) attacks. By default, the XmlReaderSettings object does not prohibit DTDs (Document Type Definitions), does not disable the resolution of external entities, and does not prevent the inclusion of external general or parameter entities.

An attacker could exploit this by sending a malicious XML document that includes an external entity. The XML parser would process the external entity, potentially leading to data exfiltration, Denial of Service (DoS), or Remote Code Execution (RCE).

For instance, an attacker could send an XML document that includes a SYSTEM entity with a URI that points to a sensitive file on the server. The XML parser would read the file and include its contents in the parsed XML document, thereby leaking sensitive information.

Steps

  • Validate and sanitize user input: Implement input validation and sanitization techniques to ensure that the XML data received is safe and does not contain any malicious code.
  • Disable external entity resolution: Configure the XML reader settings to disable external entity resolution. This prevents the application from accessing external resources or executing remote commands.
  • Use a secure XML parser: Replace the use of XmlReader and XDocument with a secure XML parser that automatically handles security concerns, such as preventing XXE attacks.
  • Implement strict XML parsing: Configure the XML parser to enforce strict parsing rules, such as disallowing the use of DTDs (Document Type Definitions) or external entity references.
  • Implement least privilege principle: Ensure that the XML processing code runs with the least privileges necessary to perform its intended functionality. Limit access to sensitive resources or operations.
  • Keep software up to date: Regularly update the ASP.NET Core framework and any XML parsing libraries used in the application to benefit from security patches and improvements.
  • Educate developers: Provide training and guidance to developers on secure coding practices, including the risks associated with XML injection vulnerabilities and how to prevent them.

Compliant code

using System.Xml;
using System.IO;

public class XMLController : Controller
{
[HttpPost]
public IActionResult Post([FromBody] string xmlData)
{
var xmlReaderSettings = new XmlReaderSettings
{
DtdProcessing = DtdProcessing.Prohibit,
XmlResolver = null
};

using (var stringReader = new StringReader(xmlData))
using (var xmlReader = XmlReader.Create(stringReader, xmlReaderSettings))
{
while (xmlReader.Read())
{
// Process XML data...
}
}

return Ok();
}
}

The updated code includes several changes to mitigate the risk of XML injection (XXE) attacks:

  1. Disable DTD Processing: The DtdProcessing property of XmlReaderSettings is set to DtdProcessing.Prohibit to disable DTD (Document Type Definition) processing. DTDs can be used in XXE attacks to define external entities that can access local or remote content.

  2. Disable External Entity Resolution: The XmlResolver property of XmlReaderSettings is set to null to disable the resolution of external entities. This prevents the XML parser from accessing external resources, which can be exploited in XXE attacks to exfiltrate data or execute remote commands.

  3. Secure XML Parsing: The XML data is parsed using XmlReader with the secure settings defined above. XmlReader is a forward-only reader that provides a fast, non-cached, forward-only way of generating streams or files containing XML data.

  4. Implement Least Privilege Principle: The XML processing code is run with the least privileges necessary to perform its intended functionality. This limits the potential damage in case of a successful XXE attack.

  5. Dispose Resources Properly: The StringReader and XmlReader objects are wrapped in using statements to ensure that they are properly disposed after use. This helps to prevent resource leaks that could be exploited in denial-of-service (DoS) attacks.

Remember to keep your ASP.NET Core framework and any XML parsing libraries up to date to benefit from security patches and improvements. Also, provide training and guidance to developers on secure coding practices, including the risks associated with XML injection vulnerabilities and how to prevent them.

References