Castor Library Default Configuration could lead to XML External Entity (XXE) Attack Vulnerability Type: Local or Remote File Disclosure Reporter: Ron Gutierrez (rgutierrez@gdssecurity.com) and Adam Bixby ( abixby@gdssecurity.com) Company: Gotham Digital Science (gdslabs@gdssecurity.com) Affected Software: Caster 1.3.3-RC1 Library and earlier CVE-Reference - CVE-2014-3004 Severity: High =========================================================== Summary =========================================================== The Castor library is an Open Source data-binding framework for Java applications. One of its most useful functions are to provide for easy implementations of Java-to-XML binding. The library’s unmarshalling class, however, is susceptible to XML External Entity (XXE) attacks. If the XML that is being passed to the unmarshalling function is controllable by an end user, there is the potential that they could retrieve local resources, download malicious code from other servers, and/or open arbitrary TCP connections. For more information on XXE, please see https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing =========================================================== Technical Details =========================================================== The Castor library’s unmarshalling functionality, if used with default settings, does not prevent the referencing of external entities or doctype declarations, opening up any application that utilizes this functionality to an XXE attack. Under the hood, the Castor library is using the Xerces SAX Parser, which needs to be configured securely in order to prevent these types of attacks. Castor does not have these secure settings turned on in the default configuration file and does not make reference to them anywhere in their documentation. XXE attacks come about due to the way in which XML parsers in general handle XML documents containing external entities. When an XML parser encounters a DOCTYPE declaring an external entity, it expands all instances of the entity with the contents of the URI reference that is being defined. For example, consider an XML document such as the following: ]> &xxe; When the XML parser encounters "&xxe;” it will embed the contents of "/etc/passwd", which may then be returned in the server’s response, typically in an exception message. When you utilize the Castor library, the castor.properties file contains references to attributes that can be added to your SAX Parser configuration, however, it does not enable any of these hardening references out of the box. Unless the developer is acutely aware that they need to add these hardening references to their configuration, their application will be potentially vulnerable. =========================================================== Proof-of-Concept Code and Exploit =========================================================== Now let’s look at how Castor handles unmarshalling calls to show how an application could be vulnerable: In this simple class, we create Person object: ..snip.. public class Person implements java.io.Serializable { /** The name of the person */ private String name = null; /** The Date of birth */ private Date dob = null; /** Creates a Person with no name */ public Person() { super(); } /** Creates a Person with the given name */ public Person(String name) { this.name = name; } ..snip.. Next, we generate a class that takes in external XML data to convert the XML document to a Person Object using the unmarshalling function: public static Person deserializePersonWithStatic(String xmlInput) { StringReader xmlReader = new StringReader(xmlInput); Person aPerson = null; try { aPerson = (Person) Unmarshaller.unmarshal(Person.class, xmlReader); } catch (Exception e) { System.out.println("Failed to unmarshal the xml"); e.printStackTrace(); } return aPerson; } If our application took in the XML data from a user controllable location and passed it through this unmarshalling function, the end user could use this functionality to view local resources on the application’s hosting server. For example, look at the following Servlet that takes in XML data from the Request: public class GeneratePerson extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String evilPersonXML = req.getParameter(“person”); Person anotherPerson = deserializePersonWithStatic(evilPersonXML); if(anotherPerson == null) { System.out.println("No Person Object set"); } else { System.out.println("XXE Person name: " + anotherPerson.getName()); } What would happen if we passed the following string into the “person” request parameter value?: ] >&x3; The output would be the following: XXE Person name: ## # User Database # # Note that this file is consulted directly only when the system is running # in single-user mode. At other times this information is provided by # Open Directory. # # See the opendirectoryd(8) man page for additional information about # Open Directory. ## nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false root:*:0:0:System Administrator:/var/root:/bin/sh daemon:*:1:1:System Services:/var/root:/usr/bin/false ..snip.. As you can see, the unmarshalling function allowed external entities to be referenced and therefore the contents of the server’s /etc/passwd file was set within the “name” variable of the deserialized Person object. =========================================================== Recommendation =========================================================== Upgrade to Castor version 1.3.3 which now disables external entities by default. Alternatively, the manual fix for this issue is actually very simple. The main Castor configuration file (castor.properties) can be used to specify which XML features should be enable/disabled. In order to prevent the parser from reading external entities , the external-general-entities and the external-parameter-entities should be disable. Additionally, the disallow-doctype-decl option should be turned on. The following is what the entry in the caster.properties file should look like: # Comma separated list of SAX 2 features that should be enabled # for the default parser. # org.exolab.castor.sax.features=\ http://apache.org/xml/features/disallow-doctype-decl # Comma separated list of SAX 2 features that should be disabled # for the default parser. # org.exolab.castor.sax.features-to-disable=\ http://xml.org/sax/features/external-general-entities,\ http://xml.org/sax/features/external-parameter-entities,\ http://apache.org/xml/features/nonvalidating/load-external-dtd =========================================================== About Gotham Digital Science =========================================================== Gotham Digital Science (GDS) is a specialist security consulting company focused on helping our clients find, fix, and prevent security bugs in mission critical network infrastructure, web-based software applications, mobile apps and embedded systems. GDS is also committed to contributing to the security and developer communities through sharing knowledge and resources such as blog posts, security tool releases, vulnerability disclosures, and sponsoring and presenting at various industry conferences. For more information on GDS, please contact info@gdssecurity.com or visit http://www.gdssecurity.com. -- *Ron Gutierrez* Gotham Digital Science 125 Maiden Lane Third Floor – New York, NY 10038 [Office] 212.514.8318 x6 [Mobile] 718-213-0525 [Fax] 646.349.3911 [Blog] http://blog.gdssecurity.com -- Send safely and sleep soundly with our secure file sharing service, SendSafely (www.sendsafely.com) ------------------------------ This message is private and confidential. If you have received this message in error, please notify us and remove it from your system.