Skip to content

Commit ab62bb6

Browse files
committed
Consider second parameter of Node.selectNodes
1 parent d72dd9b commit ab62bb6

File tree

2 files changed

+17
-6
lines changed
  • java/ql
    • src/semmle/code/java/security
    • test/experimental/query-tests/security/CWE-643

2 files changed

+17
-6
lines changed

java/ql/src/semmle/code/java/security/XPath.qll

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ private class XPathEvaluation extends MethodAccess {
1818
m.hasName(["evaluate", "evaluateExpression", "compile"])
1919
)
2020
}
21+
22+
Expr getSink() { result = this.getArgument(0) }
2123
}
2224

2325
/** The interface `org.dom4j.Node` */
@@ -27,16 +29,25 @@ private class Dom4JNode extends Interface {
2729

2830
/** A call to methods of any class implementing the interface `Node` that evaluate XPath expressions */
2931
private class NodeXPathEvaluation extends MethodAccess {
32+
Expr sink;
33+
3034
NodeXPathEvaluation() {
31-
exists(Method m |
32-
this.getMethod() = m and m.getDeclaringType().getASourceSupertype*() instanceof Dom4JNode
35+
exists(Method m, int index |
36+
this.getMethod() = m and
37+
m.getDeclaringType().getASourceSupertype*() instanceof Dom4JNode and
38+
sink = this.getArgument(index)
3339
|
3440
m.hasName([
3541
"selectObject", "selectNodes", "selectSingleNode", "numberValueOf", "valueOf", "matches",
3642
"createXPath"
37-
])
43+
]) and
44+
index = 0
45+
or
46+
m.hasName("selectNodes") and index in [0, 1]
3847
)
3948
}
49+
50+
Expr getSink() { result = sink }
4051
}
4152

4253
/**
@@ -47,7 +58,7 @@ abstract class XPathInjectionSink extends DataFlow::Node { }
4758

4859
private class DefaultXPathInjectionSink extends XPathInjectionSink {
4960
DefaultXPathInjectionSink() {
50-
exists(NodeXPathEvaluation sink | sink.getArgument(0) = this.asExpr()) or
51-
exists(XPathEvaluation sink | sink.getArgument(0) = this.asExpr())
61+
exists(NodeXPathEvaluation sink | sink.getSink() = this.asExpr()) or
62+
exists(XPathEvaluation sink | sink.getSink() = this.asExpr())
5263
}
5364
}

java/ql/test/experimental/query-tests/security/CWE-643/A.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public void handle(HttpServletRequest request) throws Exception {
107107
org.dom4j.Document document = reader.read(new ByteArrayInputStream(xmlStr.getBytes()));
108108
document.selectObject("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
109109
document.selectNodes("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
110-
document.selectNodes("/users/user[@name='test']", "/users/user[@pass='" + pass + "']"); // Safe-ish
110+
document.selectNodes("/users/user[@name='test']", "/users/user[@pass='" + pass + "']"); // $hasXPathInjection
111111
document.selectSingleNode("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
112112
document.valueOf("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
113113
document.numberValueOf("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection

0 commit comments

Comments
 (0)