XML file parsing and XML external entity injection protection

XML external entities injection
Example:

InputStream is = Test01.class.getClassLoader().getResourceAsStream("evil.xml");//source
XMLInputFactory xmlFactory  = XMLInputFactory.newInstance();  
XMLEventReader reader = xmlFactory.createXMLEventReader(is);  //sink

If the evil.xml file contains the following content, it may cause xml external entity injection

 <?xml version="1.0" encoding="ISO-8859-1"?>
 <!DOCTYPE foo [  
 <!ELEMENT foo ANY >
 <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>

XML file analysis and XXE protection

DOM
The full name of DOM is Document Object Model, also known as Document Object Model. In the application, the DOM-based XML parser converts an XML document into a collection of object models (commonly called DOM trees). The application precisely manipulates the XML document data by operating on the object model.

import javax.xml.parsers.DocumentBuilder;  
import javax.xml.parsers.DocumentBuilderFactory;  

...
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  
        System.out.println("class name: " + dbf.getClass().getName());  
        // step 2:获得具体的dom解析器  
        DocumentBuilder db = dbf.newDocumentBuilder(); 
        // step3: 解析一个xml文档,获得Document对象(根结点)  
        Document document = db.parse(new File("candidate.xml"));  
        NodeList list = document.getElementsByTagName("PERSON");  


Protection Recommendation 1

 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      // 这是优先选择. 如果不允许DTDs (doctypes) ,几乎可以阻止所有的XML实体攻击
      String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
      dbf.setFeature(FEATURE, true);

        catch (ParserConfigurationException e) {
            // This should catch a failed setFeature feature
            logger.info("ParserConfigurationException was thrown. The feature '" +
                        FEATURE +
                        "' is probably not supported by your XML processor.");
            ...
        }
        catch (SAXException e) {
            // On Apache, this should be thrown when disallowing DOCTYPE
            logger.warning("A DOCTYPE was passed into the XML document");
            ...
        }
        catch (IOException e) {
            // XXE that points to a file that doesn't exist
            logger.error("IOException occurred, XXE may still possible: " + e.getMessage());
            ...
        }



Protection Recommendation 2

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      // 如果不能完全禁用DTDs,最少采取以下措施
      FEATURE = "http://xml.org/sax/features/external-general-entities";
      dbf.setFeature(FEATURE, false);

      FEATURE = "http://xml.org/sax/features/external-parameter-entities";
      dbf.setFeature(FEATURE, false);

      // and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks" (see reference below)
      dbf.setXIncludeAware(false);
      dbf.setExpandEntityReferences(false);

      // And, per Timothy Morgan: "If for some reason support for inline DOCTYPEs are a requirement, then ensure the entity settings are disabled (as shown above) and beware that SSRF attacks(http://cwe.mitre.org/data/definitions/918.html) and denial of service attacks (such as billion laughs or decompression bombs via "jar:") are a risk."
      ...

        catch (ParserConfigurationException e) {
            // This should catch a failed setFeature feature
            logger.info("ParserConfigurationException was thrown. The feature '" +
                        FEATURE +
                        "' is probably not supported by your XML processor.");
            ...
        }
        catch (SAXException e) {
            // On Apache, this should be thrown when disallowing DOCTYPE
            logger.warning("A DOCTYPE was passed into the XML document");
            ...
        }
        catch (IOException e) {
            // XXE that points to a file that doesn't exist
            logger.error("IOException occurred, XXE may still possible: " + e.getMessage());
            ...
        }



SAX
The full name of SAX is Simple APIs for XML, that is, XML simple application program interface. Unlike DOM, the access mode provided by SAX is a sequential mode, which is a fast way to read and write XML data. When the SAX parser is used to analyze the XML document, it will trigger a series of events and activate the corresponding event processing functions. The application program uses these event processing functions to access the XML document, so the SAX interface is also called an event-driven interface. .

import javax.xml.parsers.SAXParser;  
import javax.xml.parsers.SAXParserFactory;  

        SAXParserFactory factory = SAXParserFactory.newInstance();  
        //step2: 获得SAX解析器实例  
        SAXParser parser = factory.newSAXParser();  
        //step3: 开始进行解析  
        parser.parse(new File("student.xml"), new MyHandler());  

Protection advice

参考DocumentBuilderFactory



JDOM
JDOM (Java-based Document Object Model) is an open source project, which is based on a tree structure, using pure JAVA technology to parse, generate, serialize and multiple operations on XML documents.

import org.jdom.Attribute;  
import org.jdom.Document;  
import org.jdom.Element;  
import org.jdom.input.SAXBuilder;  
import org.jdom.output.Format;  
import org.jdom.output.XMLOutputter;  

...
        SAXBuilder builder = new SAXBuilder();  
        Document doc = builder.build(new File("jdom.xml"));  
        Element element = doc.getRootElement();  



DOM4J
DOM4J (Document Object Model for Java), adopts Java collection framework, and fully supports DOM, SAX and JAXP

StAX
StAX (Streaming API for XML) is a pull analysis XML parsing technology (the analysis method based on the pull model in the stream model is called pull analysis). StAX includes two sets of APIs for processing XML, which provide different levels of abstraction. They are: pointer-based API and iterator-based API.
The interface that allows us to use a pointer-based API is javax.xml.stream.XMLStreamReader (sadly, you cannot instantiate it directly). To get an instance of it, we need to use the javax.xml.stream.XMLInputFactory class.

//获得一个XMLInputFactory实例
XMLInputFactory factory = XMLInputFactory.newInstance();  
//开始解析
XMLStreamReader reader = factory.createXMLStreamReader(new FileReader("users.xml"));  



Protection advice

XMLInputFactory factory = XMLInputFactory.newInstance();
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);  //会完全禁止DTD
XMLStreamReader reader = factory.createXMLStreamReader(new FileReader("users.xml"));  

Several methods for parsing xml files with reference to Java
Reference XML External Entity (XXE) Processing

Published 30 original articles · Like 13 · Visits 100,000+

Guess you like

Origin blog.csdn.net/u013224189/article/details/49759845