>
>
>
V5614. OWASP. Potential XXE vulnerabili…


V5614. OWASP. Potential XXE vulnerability. Insecure XML parser is used to process potentially tainted data.

The analyzer has detected the use of an insecurely configured XML parser that processes tainted data. This can make an application vulnerable to an XXE attack.

OWASP Top 10 Application Security Risks 2017 has a separate risk category for XXE attacks: A4:2017 – XML External Entities (XXE). They are also included in the A05:2021 category – Security Misconfiguration OWASP Top 10 2021.

What is an XXE attack?

XML files may contain the document type definition (DTD). DTD allows us to define and use XML entities. Entities can be fully defined inside the document (they can be a string, for example), or they can refer to external resources. That's why it's called an XXE attack: XML eXternal Entities.

External entities can be defined via URI. As a result, the XML parser processes this URI and puts the resulting content into an XML document.

The following example is an XML document that contains an external entity:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file://D:/XXETarget.txt">
]>
<foo>&xxe;</foo>

The 'xxe' entity is defined in this XML. A developer may configure a parser to process external entities. In this case, instead of '&xxe;', the parser inserts the contents of the 'D:\XXETarget.txt' file.

Thus, an attack is possible if:

  • an attacker can pass an XML file with external entities to an application, which parses this file;
  • an XML parser has an insecure configuration;
  • parsing data (entity values) can get back to an attacker.

As a result, an attacker can reveal the contents of data from the machine on which the application is running, and which is engaged in parsing the XML file.

Vulnerable code examples

PVS-Studio issues a warning if it detects an insecurely configured XML parser that processes an external data in code.

Let's look at a simple example. We have an application that accepts queries as XML files and processes items with the corresponding ID. If an XML-file has the incorrect ID, the application warns the user about it.

The application works with the following XML file format:

<?xml version="1.0" encoding="utf-8" ?>
<shop>
  <itemID>62</itemID>
</shop>

Let's say the following code fragment processes XML files:

static void ProcessItemWithID(String pathToXmlFile)
{
  XmlReaderSettings settings = new XmlReaderSettings()
  {
    XmlResolver = new XmlUrlResolver(),
    DtdProcessing = DtdProcessing.Parse
  };

  using (var fileReader = File.OpenRead(pathToXmlFile))
  {
    using (var reader = XmlReader.Create(fileReader, settings))
    {
      while (reader.Read())
      {
        if (reader.Name == "itemID")
        {
          var itemIDStr = reader.ReadElementContentAsString();
          if (long.TryParse(itemIDStr, out var itemIDValue))
          {
            // Process item with the 'itemIDValue' value
            Console.WriteLine(
              $"An item with the '{itemIDValue}' ID was processed.");
          }
          else
          {
            Console.WriteLine($"{itemIDStr} is not valid 'itemID' value.");
          }
        }
      }
     }
  }
}

For the XML file above, the application outputs the following string:

An item with the '62' ID was processed.

If we insert something else in the ID instead of the number (the "Hello world" string, for example), the application reports an error:

"Hello world" is not valid 'itemID' value.

The code runs as we expected. However, the following factors make the code vulnerable to XXE attacks:

  • the XML content comes from the user;
  • the developer configures the XML parser to process external entities;
  • the output can be passed back to the user.

Take a look at an XML file below. Attackers can use it to compromise this code fragment:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file://D:/MySecrets.txt">
]>
<shop>
  <itemID>&xxe;</itemID>
</shop>

An attacker declares the 'xxe' external entity in this file. The XML parser processes this entity. The 'D:/MySecrets.txt' file is on the machine where the application is running. As a result of the processing, the user gets the file contents (for example, 'This is an XXE attack target.'):

This is an XXE attack target. is not valid 'itemID' value.

If we want to protect ourselves from this attack, we can prohibit processing external entities — we assign the 'null' value to the 'XmlResolver' property. Also, we can prohibit or ignore DTD processing by writing 'Prohibit' / 'Ignore' to 'DtdProcessing'.

An example of secure settings:

XmlReaderSettings settings = new XmlReaderSettings()
{
  XmlResolver = null,
  DtdProcessing = DtdProcessing.Prohibit
};

Note: if you use various types, the vulnerability to XXE attacks may look different. For example, the code fragment below is also vulnerable to an XXE attack:

static void ProcessXML(String pathToXmlFile)
{
  XmlDocument xmlDoc = new XmlDocument();
  xmlDoc.XmlResolver = new XmlUrlResolver();

  using (var xmlStream = File.OpenRead(pathToXmlFile))
  {
    xmlDoc.Load(xmlStream);
    Console.WriteLine(xmlDoc.InnerText);
  }
}

Here XML is loaded via an instance of the 'XmlDocument' type. At the same time, a developer explicitly sets a dangerous value for 'XmlResolver'. DTD processing is implicitly enabled. If we want to prohibit external entities processing, we can write the 'null' value to the 'XmlResolver' property.

The analyzer also takes into account interprocedural calls. Take a look at the example:

static FileStream GetXmlFileStream(String pathToXmlFile)
{
  return File.OpenRead(pathToXmlFile);
}

static XmlDocument GetXmlDocument()
{
  XmlDocument xmlDoc = new XmlDocument()
  {
    XmlResolver = new XmlUrlResolver()
  };

  return xmlDoc;
}

static void LoadXmlInternal(XmlDocument xmlDoc, Stream input)
{
  xmlDoc.Load(input);
  Console.WriteLine(xmlDoc.InnerText);
}

static void XmlDocumentTest(String pathToXmlFile)
{
  using (var xmlStream = GetXmlFileStream(pathToXmlFile))
  {
    var xmlDoc = GetXmlDocument();
    LoadXmlInternal(xmlDoc, xmlStream);
  }
}

In this case the analyzer issues a warning for calling the 'LoadXmlInternal' method. The analyzer has detected the following:

  • the 'xmlDoc' parser obtained from the 'GetXmlDocument' method can process external entities;
  • 'xmlStream' received from the 'GetXmlStream' method contains data received from an external source (read from the file);
  • the 'xmlDoc' parser and the tainted data are passed to the 'LoadXmlInternal' method. This method processes the XML file.

Note that the analyzer also sees method parameters (available from other assemblies) as tainted data sources. You can read more about it in the article: "Why you should check values of public methods' parameters".

For example, the analyzer issues a warning of low certainty level for the following code fragment. Here the insecure data source is a parameter of a publicly available method:

public static void XmlDocumentTest(Stream xmlStream)
{
  XmlDocument doc = new XmlDocument()
  {
    XmlResolver = new XmlUrlResolver()
  };

  doc.Load(xmlStream);
  Console.WriteLine(doc.InnerText);
}

Note that settings of some XML parsers were changed in different versions of .NET Framework.

Look at the following code fragment:

static void XmlDocumentTest(String pathToXml)
{
  var xml = File.ReadAllText(pathToXml);
  XmlDocument doc = new XmlDocument();

  doc.LoadXml(xml);
  Console.WriteLine(doc.InnerText);
}

This code fragment is resistant to XXE attacks in .NET Framework 4.5.2 and newer versions. The 'XmlResolver' property has the 'null' value by default. As a result, the external entities are not processed.

In .NET Framework 4.5.1 and older versions this code fragment is vulnerable to XXE attacks — the 'XmlResolver' property is not 'null' by default, thus it processes external entities.

PVS-Studio takes into account the default settings of parsers that depend on .NET Framework / .NET version used in the analyzed project.

To protect your code from XXE attacks make sure that you disable the DTD processing and prohibit external entities processing. In various XML parsers the settings may differ. But usually, 'DtdProcessing' ('ProhibitDtd' in older versions of .NET Framework) and 'XmlResolver' properties are responsible for processing external entities.

This diagnostic is classified as: