Open In App

XML External Entity (XXE) and Billion Laughs attack

Last Updated : 14 Oct, 2020
Improve
Improve
Like Article
Like
Save
Share
Report

XXE or XML External Entity attack is a web application vulnerability that affects a website which parses unsafe XML that is driven by the user. XXE attack when performed successfully can disclose local files in the file system of the website.  XXE is targeted to access these sensitive local files of the website that is vulnerable to unsafe parsing.

Types Of XXE Attacks

  1. File Retrieval XXE: As the name implies, arbitrary files on the application server of a victim company can be exposed to the attacker, if there is an XXE vulnerable endpoint in the target system.  This can be carried out by passing an external XML entity in the user-controlled file.
  2. Blind XXE: It is possible that a target system doesn’t return data from the entities placed by the attacker still being insecure and vulnerable to XXE. This is done by trying out malformed user inputs. These include the input of length more than what the system expects, the wrong data type, special entities, etc. The intention is to make the system fail and check if throws out some sensitive information in the error response.
  3. XXE to SSRF: Even if the system doesn’t return the response with local file content to the attacker, the system can be still exploited in presence of an XXE attack. The entity can be pointed to a local IP of the target company which can be accessed only by its websites/network. Placing an intranet IP in XXE payload will make the target application call its local endpoint which the attacker won’t have access to otherwise. This type of attack is called SSRF or Server Side Request Forgery.

XML Parsing

XML is one of the commonly used data exchange formats. Data can be transferred between User and Website in XML format. Consider a website that accepts User information in form of XML. The XML that is submitted to the website looks like follows,

XML




<?xml version="1.0" encoding="ISO-8859-1"?>
<profiles>
  <profile>
    <name> Siva </name>
    <Age> 24 </Age>
    <occupation> Lead </occupation>
  </profile>
  <profile>
    <name> Subbu </name>
    <Age> 25 </Age>
    <occupation> Developer </occupation>
  </profile>
</profiles>


The website accepts this XML, parses this obtains the Name, Age, and Occupation of records in Input XML, and returns a response of processed names in return.

XML consists of a concept of entities to refer to a single object in an XML document. An entity can be defined in an XML and can be reused multiple times across the website. For example,

XML




<!ENTITY test SYSTEM "https://www.geeksforgeeks.org/DTD.dtd">
<custom>&test;;</custtom>


test is described as an Entity in an XML document and it can be reused anywhere. It is also possible to lookup an External Entity that refers to some third-party website.

Code To Parse XML Documents

There are multiple XML parsing libraries that parse XML Document and return a Queryable Object. Typically, In Java, XML is parsed as follows,

Java




import java.io.File;  
import javax.xml.parsers.DocumentBuilderFactory;  
import org.w3c.dom.NodeList;  
import org.w3c.dom.Node;  
import javax.xml.parsers.DocumentBuilder;  
import org.w3c.dom.Document;  
import org.w3c.dom.Element;  
public class GFGXMLParser 
public static void main(String[] args)   
{  
  try   
  {  
    File file = new File("/Users/Siva-5136/Downloads/Untrusted.xml");  
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();  
    DocumentBuilder db = dbFactory.newDocumentBuilder();  
    Document doc = db.parse(file);    
    NodeList nodeList = doc.getElementsByTagName("userDetails");  
      
    //Set XML XXE Related Properties 
      
      
    for (int ind = 0; ind < nodeList.getLength(); ind++)   
    {  
      Node node = nodeList.item(ind);  
      if(Node.ELEMENT_NODE == node.getNodeType() )
      {
        Element nodeElement = (Element) node;
        System.out.println(nodeElement.getElementsByTagName("uId").item(0).getTextContent());
         System.out.println(nodeElement.getElementsByTagName("uFirstName").item(0).getTextContent());  
      }
    }  
}   
    catch (Throwable e)   
    {  
            System.out.println("Exception Parsing XML ",e);               
    }  
}  
}


Carrying Out XXE Attack

Consider the input XML is used controlled. The input is not validated and directly passed to the XML parser. The user may try to upload the following XML file,

XML




<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE name
    <!ELEMENT name ANY >
  <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<profiles>
  <profile>
      <name>`&xxe;`</name>
      <address>`test`</address>
  <profile>
</profiles>


 
 

When the XML parser parses the XML input it resolves the entity named ‘xxe’ by its definition. From input, the XML entity is defined as System resource “file://etc/passwd” which is a sensitive local file on the website’s application server. The parsed XML replaces the entity with the content of this sensitive local file and may send it back to the user. This is called an XML entity attack.  

Protection Against XXE Attacks 

The website should protect itself from XXE by disabling entities in user-generated XML content before parsing them. Failing which, the website becomes vulnerable to XXE attack and hence may disclose highly sensitive private information to the attacker. There are multiple ways to disable this based on the application stack and library used to parse the XML source file.

Almost all major XML parsers provide a way to disable XML external entities in the XML parser itself.  For the above XML parsing example, the safe version of code looks like follows:

Java




import java.io.File;  
import javax.xml.parsers.DocumentBuilderFactory;  
import org.w3c.dom.NodeList;  
import org.w3c.dom.Node;  
import javax.xml.parsers.DocumentBuilder;  
import org.w3c.dom.Document;  
import org.w3c.dom.Element;  
public class GFGXMLParser 
public static void main(String[] args)   
{  
  try   
  {  
    File file = new File("/Users/Siva-5136/Downloads/Untrusted.xml");  
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();  
    DocumentBuilder db = dbFactory.newDocumentBuilder();  
    Document doc = db.parse(file);    
    NodeList nodeList = doc.getElementsByTagName("userDetails");  
      
    //Set XML XXE Related Properties 
  
    dbFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
     dbFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
     dbFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
  
      
      
    for (int ind = 0; ind < nodeList.getLength(); ind++)   
    {  
      Node node = nodeList.item(ind);  
      if(Node.ELEMENT_NODE == node.getNodeType() )
      {
        Element nodeElement = (Element) node;
        System.out.println(nodeElement.getElementsByTagName("uId").item(0).getTextContent());
         System.out.println(nodeElement.getElementsByTagName("uFirstName").item(0).getTextContent());  
      }
    }  
}   
    catch (Throwable e)   
    {  
        System.out.println("Exception Parsing XML ",e);               
    }  
}  
}


Related Vulnerabilities 

Another common vulnerability associated with XML parsing is called A Billion Laughs Attack. It uses an entity to resolve itself cyclically thereby consuming more CPU usage and causing a denial of service attack. An Example XML payload that can cause an XXE attack is as follows:

XML




<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ELEMENT lolz (#PCDATA)>
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
 <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
 <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
 <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
 <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
 <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
 <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>


The entity keeps getting resolved to itself cyclically thereby slowing down requests and causing a DOS attack on the application. A billion laughs attack can be disabling DOCTYPE as in the above code snippet completely or setting a maximum limit on the evaluation of entities.

Impact Of XXE And A Billion Laughs Attacks

  1. XXE can cause information leakage, it can leak system files that have critical data.
  2. Data obtained from XXE can be used to target websites for additional vulnerabilities.
  3. A billion Laughs can cause service outage or a Denial Of Service attack.


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads