Search This Blog

Tuesday, September 14, 2010

XML Injection

Been quite sometime since I posted something. Been looking into XML vulnerabilities and figured I'd share. The contents of this BLOG are in no means referencing any employer that I have been involved with and are soley my interests in XML injection.

When developing Web services, one would typically like to keep them secure by preventing agaisnt either Denial of Service or Security Attacks.

So what is XML Injection? If a malicious user alters the contents of an XML document by injecting XML tags, then when an XML parser tries to parse the document, security exploits can be achieved. For the scope of this BLOG, I am not creating a Web Service but explaining in plain vanilla XML and SAX as to how the exploits can occur. The same concepts of course apply to Web Services dealing with XML.

Tag Injection:
Consider the following XML Document that represents an item that is submitted
for purchase.
<item> 
    <description>Widget</description>
    <price>500.0</price>
    <quantity>1</quantity>
</item>
The above XML is represented as a JAXB Object to which it would be un-marshalled as shown below:
@XmlRootElement
public class Item {
  private String description;
  private Double price;
  private int quantity;
 
 // Setters and getters
  ....
}
When the above XML is parsed by a SAX Parser, the resulting Item object is correctly matched up with the corresponding attributes.

Consider the XML fragment altered by a malicious user who was aware of the structure:
<item> 
    <description>Widget</description>
    <price>500.0</price>
    <quantity>1</quantity>
    <!-- Additional Rows below for price and quantity -->
    <price>1.0</price>
    <quantity>1</price>
</item>
When the above document is parsed by the SAX Parser, it interprets the second element as overriding the first and thus the price reflects as 1.00 instead of 500.00. One only needs to think of the ramifications of this successful injection. Always a fan of the dollar store :-).

So how can one prevent the same from happening? Validating the received XML agaisnt an XSD will catch the fallacy in the structure. The following represents a simple XSD for the document:
<xs:schema
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns="http://www.welflex.com/item"
 elementFormDefault="qualified">
 <xs:element name="item">
  <xs:complexType>
   <xs:sequence>
    <xs:element name="description" type="xs:string"></xs:element>
    <xs:element name="price" type="xs:decimal"></xs:element>
    <xs:element name="quantity" type="xs:integer"></xs:element>
   </xs:sequence>
  </xs:complexType>
 </xs:element>
</xs:schema>
Now when the SAX Parser validates agaisnt the schema provided with the malicious XML, an exception would be risen to the effect of:
javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException: cvc-complex-type.2.4.d: Invalid content was found starting with element 'price'. No child element is expected at this point.]
 at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315)
 at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:503)
....

As to why an attacker would not simply submit a whole new document with malicious data rather than injecting the same, well I do not have a concrete answer for that and can only suppose it might have to do with source system validation by the target system?

XXE or Xml EXternal Entity Attack:
External entity references in XML allow data from outside the main document to be embedded into the XML document. This "feature" allows for a malicious user to either gain access to sensitive information and/or create a denial of service attack.

Consider the following malevolent XML fragment:
<Person>
  <FirstName>Sanjay</FirstName>
  <LastName>Acharya</LastName>
</Person>

Now, consider the same XML shown above with small modifications made by our friendly neighborhood attacker:
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<Person>
  <FirstName>Sanjay</FirstName>
  <LastName>Acharya&xxe;</LastName>
</Person>

When an XML parser such as a SAX Parser reads the XML in, if running for example on a *NIX system will result in the loading of the contents of the /etc/passwd file into the contents of the resulting parsed document. If the same is returned to the person invoking the attack, well you can imagine their glee at accessing this sensitive data.

The above XML read into a Person object would look like:
Person:Person [firstName=Donald, lastName=Duckroot:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
.........
couchdb:x:106:113:CouchDB Administrator,,,:/var/lib/couchdb:/bin/bash
haldaemon:x:107:114:Hardware abstraction layer,,,:/var/run/hald:/bin/false
speech-dispatcher:x:108:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/sh
kernoops:x:109:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false
saned:x:110:116::/home/saned:/bin/false
pulse:x:111:117:PulseAudio daemon,,,:/var/run/pulse:/bin/false
gdm:x:112:119:Gnome Display Manager:/var/lib/gdm:/bin/false
johndoe:x:1000:1000: John Doe,,,:/home/johndoe:/bin/bash

If the server program parsing the XML was running as root, then the attacker could also access the /etc/shadow file. Using External entity injection, the possibilities of retrieving sensitive information or creating a re-cursive failure and thus denial of service is definitely enticing for an attacker.

Clearly the way to restrict this from happening is either to scan requests at the network level or follow a direction to strictly enforce which entities can be resolved. A strategy to combat the same is explained at Secure Coding.

Another option to consider is to provide a custom SAXParserFactory that will employ the EntityResolver mentioned in the SecureCoding site but is made available either for the entire VM or a particular module. One can employ a custom SAXParserFactory class by registering in a jaxp.properties file in the jre/lib directory or via META-INF/services of an individual module.

An example of a Filtering SAX Parser Factory that could be employed using one of the above mentioned strategies is shown below. The factory delegates to the default factory to create a parser but then adds an EntityResolver to the parser before providing it back to the caller.
public class FilteringSaxParserFactory extends SAXParserFactory {
  // Delegate to this parser
  private SAXParserFactory delegate;
  
  // Delegate class
  private static final String DELEGATE_CLASS = "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl";
  
  // Allowed Entity Paths
  private Set<String> allowedEntityPaths;
  
  public FilteringSaxParserFactory() {
    delegate = SAXParserFactory.newInstance(DELEGATE_CLASS, Thread.currentThread().getContextClassLoader());
    delegate.setNamespaceAware(true);
    delegate.setValidating(true);
    allowedEntityPaths = new HashSet<String>();
    allowedEntityPaths.add("/usr/local/entity/somefile");
  }
  
  @Override
  public boolean getFeature(String name) throws ParserConfigurationException,
    SAXNotRecognizedException,
    SAXNotSupportedException {
    return delegate.getFeature(name);
  }

  @Override
  public SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
    SAXParser parser = delegate.newSAXParser();
    XMLReader xmlReader = parser.getXMLReader();
    xmlReader.setEntityResolver(new EntityResolver() {
      
      @Override
      public InputSource resolveEntity(String publicId, String systemId) throws SAXException,
        IOException {
        if (allowedEntityPaths.contains(systemId)) {
          return new InputSource(systemId);
        }
        
        // Return blank path to prevent untrusted entities
        return new InputSource();
      }
    });
    
    return parser;
  }
  ....
}

XML Bomb Attack:
Another form of an XML attack is whats known as an XML Bomb. The bomb is small XML fragment that makes the data provided grow exponentially during the parsing of the document thus leading to extensive memory consumption and thus room for a denial of service attack.

Consider the following XML Bomb:
<!DOCTYPE item["
       <!ENTITY item "item">
       <!ENTITY item1 "&item;&item;&item;&item;&item;&item;">
       <!ENTITY item2 "&item1;&item1;&item1;&item1;&item1;&item1;&item1;&item1;&item1;">
       <!ENTITY item3 "&item2;&item2;&item2;&item2;&item2;&item2;&item2;&item2;&item2;">
       <!ENTITY item4 "&item3;&item3;&item3;&item3;&item3;&item3;&item3;&item3;&item3;">
       <!ENTITY item5 "&item4;&item4;&item4;&item4;&item4;&item4;&item4;&item4;&item4;">
       <!ENTITY item6 "&item5;&item5;&item5;&item5;&item5;&item5;&item5;&item5;&item5;">
       <!ENTITY item7 "&item6;&item6;&item6;&item6;&item6;&item6;&item6;&item6;&item6;">
       <!ENTITY item8 "&item7;&item7;&item7;&item7;&item7;&item7;&item7;&item7;&item7;">
      ]>
      <item>
        <description>&item8;</description>
        <price>500.0</price>
        <quantity>1</quantity>
       </item>

When attempting to Parse the above fragment, the SAX parser will stop (a feature introduced in JDK 1.4.2)
with the following error:
javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException: The parser has encountered more than "64,000" entity expansions in this document; this is the limit imposed by the application.]
 at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315)
 ... 26 more
Note the fact that the parser complains about finding more than 64,000 entity expansions. The number of entity expansions is a property that can be controlled via "-DentityExpansionLimit".

A lot of the above mentioned scenarios could be reduced by ensuring XSD validation and not using DTD's. DTD's can be totally prevented as well by setting the property "http://apache.org/xml/features/disallow-doc-type-decl" to true. If set, then any XML being parsed that has a DOC Type declaration will cause a fatal parsing error.

An example demonstrating the XML exploits can be downloaded HEREE. Note that to witness the XXE injection, one would need to run the same on a *NIX system. The example provided does not upload private information and is only for demonstration purposes.

Oh well, keeping this BLOG limited in content. Have not even looked into XPath XML injection. Quite interesting, I only wonder how many Web Services are out there where Tag injection exploits can be used on them.

Links I found of value:
1. Preventing External Entity Attacks
2. Testing for XML Injection