Checker Xxe

belongs to group Basic
Identify potential external XML entity reference attacks

Frameworks supported by this checker

  • java up to 11
  • android up to API level 28
  • dotnet

Warnings generated by this checker

  • XXEAttackWarning: a method call might perform an unrestricted XML external entity reference [ CWE611 ]

Options accepted by this checker

  • none

Annotations understood by this checker

  • none


Description

This checker finds code that parses XML files without turning off the loading and parsing of external entities referenced in the XML files. This can lead to security problems, since such entities might be downloaded from insecure servers or from servers that lead to out of memory or denial of service. As OWASP puts it, An XML External Entity attack is a type of attack against an application that parses XML input. This attack occurs when XML input containing a reference to an external entity is processed by a weakly configured XML parser. This attack may lead to the disclosure of confidential data, denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts.

Action: Turn off the automatic resolution and download of external entities referenced from XML files, before parsing such files. This can be done in different ways, depending on the kind of XML parser that is used. Check here for the correct solution for each kind of parsers.

This checker finds code that parses XML files without turning off the loading and parsing of external entities referenced in the XML files. This can lead to security problems, since such entities might be downloaded from insecure servers or from servers that lead to out of memory or denial of service. As OWASP puts it, An XML External Entity attack is a type of attack against an application that parses XML input. This attack occurs when XML input containing a reference to an external entity is processed by a weakly configured XML parser. This attack may lead to the disclosure of confidential data, denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts.

Action: Turn off the automatic resolution and download of external entities referenced from XML files, before parsing such files. This can be done in different ways, depending on the kind of XML parser that is used. Check here for the correct solution for each kind of parsers.

Examples

Consider the following program:

public class XxeAttacks {

  public @EntryPoint void test1a(InputStream is) throws ParserConfigurationException, SAXException, IOException {
    DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    db.parse(is);
  }

  public @EntryPoint void test2a(InputStream is) throws ParserConfigurationException, SAXException, IOException {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
    dbf.setFeature(FEATURE, true);
    DocumentBuilder db = dbf.newDocumentBuilder();
    db.parse(is);
  }

  public @EntryPoint void test3a(InputStream is) throws ParserConfigurationException, SAXException, IOException {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
    dbf.setFeature(FEATURE, true);
    dbf.setFeature(FEATURE, false);
    DocumentBuilder db = dbf.newDocumentBuilder();
    db.parse(is);
  }

  public @EntryPoint void test4a(InputStream is) throws ParserConfigurationException, SAXException, IOException {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
    dbf.setFeature(FEATURE, true);
    dbf.setFeature("completely irrelevant", false);
    DocumentBuilder db = dbf.newDocumentBuilder();
    db.parse(is);
  }

  public @EntryPoint void test5a(InputStream is) throws ParserConfigurationException, SAXException, IOException {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
    if (System.currentTimeMillis() % 2 == 0)
      dbf.setFeature(FEATURE, true);
    DocumentBuilder db = dbf.newDocumentBuilder();
    db.parse(is);
  }
}

This checker issues the following warnings:

XxeAttacks.java:5: [Xxe: XXEAttackWarning] This call to method "parse" seems to perform unrestricted XML external entity reference. This might lead to information exposure or denial of service attacks
XxeAttacks.java:22: [Xxe: XXEAttackWarning] This call to method "parse" seems to perform unrestricted XML external entity reference. This might lead to information exposure or denial of service attacks
XxeAttacks.java:40: [Xxe: XXEAttackWarning] This call to method "parse" seems to perform unrestricted XML external entity reference. This might lead to information exposure or denial of service attacks

since the XML parsing performed at lines 5, 22 and 40 is performed without turning off the automatic parsing of XML entities referenced in the XML file. Note that the XML parsing performed at line 12 occurs with a document builder factory whose http://apache.org/xml/features/disallow-doctype-decl feature is set to true. Hence, no external entity is parsed there. Instead, at line 20 the feature is reset to false, hence a warning is issued at line 22. The feature set at line 29 is irrelevant, hence no warning is issued at line 31. In the final example, the feature is set at line 38, but not for all executions, hence a warning is issued at line 40.

In this example, the programmer should always set to true the http://apache.org/xml/features/disallow-doctype-decl feature, for every execution path, before parsing the XML file.

Consider the following program:

using System;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Xml.Xsl;

namespace DocumentationExamples
{

    public partial class Xxe
    {
        public static void Main(string[] args)
        { }

        public void UnsafeXmlReader(string xml)
        {
            XmlReader myReader = XmlReader.Create(new StringReader(xml), new XmlReaderSettings() { DtdProcessing = DtdProcessing.Parse });
            while (myReader.Read())
            {
                Console.WriteLine(myReader.Value);
            }
        }
        public void UnsafeXmlTextReader(string xml)
        {
            XmlTextReader myReader = new XmlTextReader(new StringReader(xml));
            while (myReader.Read())
            {
                Console.WriteLine(myReader.Value);
            }
        }
        public void UnsafeXmlDocumentReader(string xml)
        {
            XmlDocument xmlDoc = new XmlDocument
            {
                XmlResolver = new XmlUrlResolver()
            };
            xmlDoc.LoadXml(xml);
        }
        public void UnsafeXPathNavigator(string xml)
        {
            XPathDocument doc = new XPathDocument(new StringReader(xml));
            XPathNavigator nav = doc.CreateNavigator();
        }
        public void UnsafeXslCompiledTransform(string input, string toTransform)
        {
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load(XmlReader.Create(new StringReader(input), new XmlReaderSettings() { DtdProcessing = DtdProcessing.Parse }));
            using (XmlWriter writer = XmlWriter.Create("books.html"))
                xslt.Transform(XmlReader.Create(new StringReader(toTransform), new XmlReaderSettings() { DtdProcessing = DtdProcessing.Parse }), writer);
        }
        public void UnsafeXDocument(string xml)
        {
            XmlReader myReader = XmlReader.Create(new StringReader(xml), new XmlReaderSettings() { DtdProcessing = DtdProcessing.Parse });
            XDocument xRoot = XDocument.Load(myReader);
        }
        public void UnsafeXmlDictionaryReader(string xml)
        {
            XmlReader myReader = XmlReader.Create(new StringReader(xml), new XmlReaderSettings() { DtdProcessing = DtdProcessing.Parse });
            XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(myReader);
        }
    }
}

This checker issues the following warnings:

DocumentationExamples.cs:19: [Xxe: XXEAttackWarning] This call to method "Read" seems to perform unrestricted XML external entity reference. This might lead to information exposure or denial of service attacks
DocumentationExamples.cs:27: [Xxe: XXEAttackWarning] This call to method "Read" seems to perform unrestricted XML external entity reference. This might lead to information exposure or denial of service attacks
DocumentationExamples.cs:38: [Xxe: XXEAttackWarning] This call to method "LoadXml" seems to perform unrestricted XML external entity reference. This might lead to information exposure or denial of service attacks
DocumentationExamples.cs:43: [Xxe: XXEAttackWarning] This call to method "CreateNavigator" seems to perform unrestricted XML external entity reference. This might lead to information exposure or denial of service attacks
DocumentationExamples.cs:48: [Xxe: XXEAttackWarning] This call to method "Load" seems to perform unrestricted XML external entity reference. This might lead to information exposure or denial of service attacks
DocumentationExamples.cs:50: [Xxe: XXEAttackWarning] This call to method "Transform" seems to perform unrestricted XML external entity reference. This might lead to information exposure or denial of service attacks
DocumentationExamples.cs:55: [Xxe: XXEAttackWarning] This call to method "Load" seems to perform unrestricted XML external entity reference. This might lead to information exposure or denial of service attacks
DocumentationExamples.cs:60: [Xxe: XXEAttackWarning] This call to method "CreateDictionaryReader" seems to perform unrestricted XML external entity reference. This might lead to information exposure or denial of service attacks

since the XML parsing performed at lines 19, 27 and 38 is performed without turning off the automatic parsing of XML entities referenced in the XML file. Hence, no external entity is parsed there. Instead, at line 20 the feature is reset to false, hence a warning is issued at line 22. The feature set at line 29 is irrelevant, hence no warning is issued at line 31. The feature is set at line 36, but not for all executions, hence a warning is issued at line 38. The other warnings are referred to other component that manage and manipulate Xml format and subject to potential Xxe attacks: XPathNavigator at line 43, XslCompiledTransform at lines 48 and 50, XDocument at line 55 and XmlDictionaryReader at line 60.