...
Consider the following XML schema.
Code Block |
---|
<users><users> <user><user> <login>Utah</login><login>Utah</login> <password>C^f3</password><password>C^f3</password> </user></user> <user><user> <login>Bohdi</login><login>Bohdi</login> <password>C@fe</password><password>C@fe</password> </user></user> <user><user> <login>Busey</login><login>Busey</login> <password>cAf3</password><password>cAf3</password> </user> </users></user> </users> |
Untrusted code may attempt to retrieve user details from this file with an XPath statement constructed dynamically from user input.
Code Block |
---|
str_query = ""//users/user[LoginID/text()= "" &amp; login &amp; "" and password/text()="" &amp; password &amp; "]""]" |
An attacker may specify input such as, login = ' or 1=1
and password = ' or 1=1
, yielding the following query string.
...
Code Block | ||
---|---|---|
| ||
class XpathInjection { private boolean doLogin(String loginID, String password) throws ParserConfigurationException, SAXException,IOException, XPathExpressionException { DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse(""users.xml""); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); XPathExpression expr = xpath.compile(""//users/user[login/text()='"" + loginID +"'""'" + ""and password/text()='""+password+""' ]""); Object result = expr.evaluate(doc, XPathConstants.NODESET); NodeList nodes = (NodeList) result; // Print first names to the console for (int i = 0; i << nodes.getLength(); i++) { System.out.println(nodes.item(i).getNodeValue());} return (nodes.getLength() >>= 1); } } |
Compliant Solution
...
Code Block | ||
---|---|---|
| ||
Document doc = new Builder().build(""users.xml""); XQuery xquery = new XQueryFactory().createXQuery(new File(""login.xry"")); Map queryVars= new HashMap(); queryVars.put("loginid""loginid", "Utah""Utah"); // user name hardcoded for illustrative purposes queryVars.put("password""password", "securecoding""securecoding"); // password hardcoded for illustrative purposes Nodes results = xquery.execute(doc, null, queryVars).toNodes(); for (int i=0; i << results.size(); i++) { System.out.println(results.get(i).toXML()); } |
...
Wiki Markup |
---|
\[[Fortify 08|AA. Java References#Fortify 08]\] ""Input Validation and Representation: XML Injection"" \[[Sen 07|AA. Java References#Sen 07]\] \[[Sun 06|AA. Java References#Sun 06]\] [Ensure Data Security|http://java.sun.com/developer/technicalArticles/xml/jaxp1-3/index.html#Ensure%20Data%20Security] \[[OWASP 05|AA. Java References#OWASP 05]\] [Testing for XPath Injection|http://www.owasp.org/index.php/XPath_Injection_Testing_AoC] \[[MITRE 09|AA. Java References#MITRE 09]\] [CWE ID 643|http://cwe.mitre.org/data/definitions/247.html] ""Failure to Sanitize Data within XPath Expressions (aka 'XPath injection')"" |
...
IDS05-J. Prevent XML Injection 10. Input Validation and Data Sanitization (IDS) IDS07-J. Understand how escape characters are interpreted when String literals are compiled