Skip to content

Commit 7646855

Browse files
committed
Add safe example for dom4j
1 parent 926fedb commit 7646855

File tree

5 files changed

+96
-7
lines changed

5 files changed

+96
-7
lines changed

java/ql/src/Security/CWE/CWE-643/XPathInjection.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,19 @@
5858
// Bad Dom4j
5959
org.dom4j.io.SAXReader reader = new org.dom4j.io.SAXReader();
6060
org.dom4j.Document document = reader.read(new InputSource(new StringReader(xmlStr)));
61-
isExist = document.selectSingleNode("/users/user[@name='" + user + "' and @pass='" + pass + "']").hasContent();
61+
isExist = document.selectSingleNode("/users/user[@name='" + user + "' and @pass='" + pass + "']") != null;
6262
// or document.selectNodes
6363
System.out.println(isExist);
64+
65+
// Good Dom4j
66+
org.jaxen.SimpleVariableContext svc = new org.jaxen.SimpleVariableContext();
67+
svc.setVariableValue("user", user);
68+
svc.setVariableValue("pass", pass);
69+
String xpathString = "/users/user[@name=$user and @pass=$pass]";
70+
org.dom4j.XPath safeXPath = document.createXPath(xpathString);
71+
safeXPath.setVariableContext(svc);
72+
isExist = safeXPath.selectSingleNode(document) != null;
73+
System.out.println(isExist);
6474
}
6575
} catch (ParserConfigurationException e) {
6676

java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,12 @@ public void handle(HttpServletRequest request) throws Exception {
110110
String expression4 = "/users/user[@name=$user and @pass=$pass]";
111111
xpath.setXPathVariableResolver(v -> {
112112
switch (v.getLocalPart()) {
113-
case "user":
114-
return user;
115-
case "pass":
116-
return pass;
117-
default:
118-
throw new IllegalArgumentException();
113+
case "user":
114+
return user;
115+
case "pass":
116+
return pass;
117+
default:
118+
throw new IllegalArgumentException();
119119
}
120120
});
121121
xpath.evaluate(expression4, doc, XPathConstants.BOOLEAN); // Safe
@@ -154,5 +154,13 @@ public void handle(HttpServletRequest request) throws Exception {
154154
Namespace namespace = new Namespace("prefix", "http://some.uri.io");
155155
namespace.createPattern("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
156156
namespace.createXPathFilter("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
157+
158+
org.jaxen.SimpleVariableContext svc = new org.jaxen.SimpleVariableContext();
159+
svc.setVariableValue("user", user);
160+
svc.setVariableValue("pass", pass);
161+
String xpathString = "/users/user[@name=$user and @pass=$pass]";
162+
org.dom4j.XPath safeXPath = document.createXPath(xpathString); // Safe
163+
safeXPath.setVariableContext(svc);
164+
safeXPath.selectSingleNode(document); // Safe
157165
}
158166
}

java/ql/test/stubs/dom4j-2.1.1/org/dom4j/XPath.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public interface XPath extends NodeFilter {
4545

4646
void setNamespaceURIs(Map<String, String> map);
4747

48+
void setVariableContext(org.jaxen.VariableContext variableContext);
4849
}
4950

5051
/*

java/ql/test/stubs/dom4j-2.1.1/org/dom4j/xpath/DefaultXPath.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ public void sort(List<Node> list, boolean distinct) {
9191
public void setNamespaceURIs(Map<String, String> map) {
9292
}
9393

94+
@Override
95+
public void setVariableContext(org.jaxen.VariableContext variableContext) {
96+
}
97+
9498
}
9599

96100
/*
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* $Header$
3+
* $Revision$
4+
* $Date$
5+
*
6+
* ====================================================================
7+
*
8+
* Copyright 2000-2002 bob mcwhirter & James Strachan.
9+
* All rights reserved.
10+
*
11+
* Redistribution and use in source and binary forms, with or without
12+
* modification, are permitted provided that the following conditions are
13+
* met:
14+
*
15+
* * Redistributions of source code must retain the above copyright
16+
* notice, this list of conditions and the following disclaimer.
17+
*
18+
* * Redistributions in binary form must reproduce the above copyright
19+
* notice, this list of conditions and the following disclaimer in the
20+
* documentation and/or other materials provided with the distribution.
21+
*
22+
* * Neither the name of the Jaxen Project nor the names of its
23+
* contributors may be used to endorse or promote products derived
24+
* from this software without specific prior written permission.
25+
*
26+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
27+
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
29+
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
30+
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37+
*
38+
* ====================================================================
39+
* This software consists of voluntary contributions made by many
40+
* individuals on behalf of the Jaxen Project and was originally
41+
* created by bob mcwhirter <[email protected]> and
42+
* James Strachan <[email protected]>. For more information on the
43+
* Jaxen Project, please see <http://www.jaxen.org/>.
44+
*
45+
* $Id$
46+
*/
47+
48+
package org.jaxen;
49+
50+
import java.io.Serializable;
51+
52+
public class SimpleVariableContext implements VariableContext, Serializable {
53+
public SimpleVariableContext() {
54+
}
55+
56+
public void setVariableValue(String namespaceURI, String localName, Object value) {
57+
}
58+
59+
public void setVariableValue(String localName, Object value) {
60+
}
61+
62+
public Object getVariableValue(String namespaceURI, String prefix, String localName) {
63+
return null;
64+
}
65+
66+
}

0 commit comments

Comments
 (0)