*)add XQExpression.executeQuery(0) sink

This commit is contained in:
haby0
2021-02-11 16:05:48 +08:00
parent 97690b4eb7
commit a6a0fa28c4
8 changed files with 202 additions and 29 deletions

View File

@@ -20,6 +20,18 @@ public void bad(HttpServletRequest request) throws XQException {
}
}
public void bad1(HttpServletRequest request) throws XQException {
String name = request.getParameter("name");
XQDataSource xqds = new SaxonXQDataSource();
String query = "for $user in doc(\"users.xml\")/Users/User[name='" + name + "'] return $user/password";
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
XQResultSequence result = expr.executeQuery(query);
while (result.next()){
System.out.println(result.getItemAsString(null));
}
}
public void good(HttpServletRequest request) throws XQException {
String name = request.getParameter("name");
XQDataSource ds = new SaxonXQDataSource();
@@ -32,4 +44,18 @@ public void good(HttpServletRequest request) throws XQException {
while (result.next()){
System.out.println(result.getItemAsString(null));
}
}
public void good1(HttpServletRequest request) throws XQException {
String name = request.getParameter("name");
String query = "declare variable $name as xs:string external;"
+ " for $user in doc(\"users.xml\")/Users/User[name=$name] return $user/password";
XQDataSource xqds = new SaxonXQDataSource();
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
expr.bindString(new QName("name"), name, conn.createAtomicType(XQItemType.XQBASETYPE_STRING));
XQResultSequence result = expr.executeQuery(query);
while (result.next()){
System.out.println(result.getItemAsString(null));
}
}

View File

@@ -24,15 +24,15 @@ class XQueryInjectionConfig extends TaintTracking::Configuration {
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(XQueryExecuteCall execute).getPreparedExpression()
sink.asExpr() = any(XQueryPreparedExecuteCall xpec).getPreparedExpression() or
sink.asExpr() = any(XQueryExecuteCall xec).getExecuteQueryArgument()
}
/**
* Conveys taint from the input to a `prepareExpression` call to the returned prepared expression.
*/
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(XQueryParserCall parser |
pred.asExpr() = parser.getInput() and succ.asExpr() = parser)
exists(XQueryParserCall parser | pred.asExpr() = parser.getInput() and succ.asExpr() = parser)
}
}

View File

@@ -20,16 +20,33 @@ class XQueryParserCall extends MethodAccess {
}
/** A call to `XQPreparedExpression.executeQuery`. */
class XQueryExecuteCall extends MethodAccess {
XQueryExecuteCall() {
exists(Method m | this.getMethod() = m and
m.hasName("executeQuery") and
m.getDeclaringType()
.getASourceSupertype*()
.hasQualifiedName("javax.xml.xquery", "XQPreparedExpression")
class XQueryPreparedExecuteCall extends MethodAccess {
XQueryPreparedExecuteCall() {
exists(Method m |
this.getMethod() = m and
m.hasName("executeQuery") and
m.getDeclaringType()
.getASourceSupertype*()
.hasQualifiedName("javax.xml.xquery", "XQPreparedExpression")
)
}
/** Return this prepared expression. */
Expr getPreparedExpression() { result = this.getQualifier() }
}
/** A call to `XQExpression.executeQuery`. */
class XQueryExecuteCall extends MethodAccess {
XQueryExecuteCall() {
exists(Method m |
this.getMethod() = m and
m.hasName("executeQuery") and
m.getDeclaringType()
.getASourceSupertype*()
.hasQualifiedName("javax.xml.xquery", "XQExpression")
)
}
/** Return this execute query argument. */
Expr getExecuteQueryArgument() { result = this.getArgument(0) }
}

View File

@@ -1,19 +1,35 @@
edges
| XQueryInjection.java:26:37:26:65 | prepareExpression(...) : XQPreparedExpression | XQueryInjection.java:27:35:27:38 | xqpe |
| XQueryInjection.java:41:37:41:65 | prepareExpression(...) : XQPreparedExpression | XQueryInjection.java:42:35:42:38 | xqpe |
| XQueryInjection.java:53:37:53:64 | prepareExpression(...) : XQPreparedExpression | XQueryInjection.java:54:35:54:38 | xqpe |
| XQueryInjection.java:66:37:66:62 | prepareExpression(...) : XQPreparedExpression | XQueryInjection.java:67:35:67:38 | xqpe |
| XQueryInjection.java:42:23:42:50 | getParameter(...) : String | XQueryInjection.java:47:35:47:38 | xqpe |
| XQueryInjection.java:55:23:55:50 | getParameter(...) : String | XQueryInjection.java:60:53:60:57 | query |
| XQueryInjection.java:68:32:68:59 | nameStr : String | XQueryInjection.java:73:35:73:38 | xqpe |
| XQueryInjection.java:80:33:80:60 | nameStr : String | XQueryInjection.java:85:53:85:57 | query |
| XQueryInjection.java:93:28:93:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:97:35:97:38 | xqpe |
| XQueryInjection.java:105:28:105:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:109:53:109:56 | name |
| XQueryInjection.java:117:28:117:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:122:35:122:38 | xqpe |
| XQueryInjection.java:130:28:130:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:135:53:135:54 | br |
nodes
| XQueryInjection.java:26:37:26:65 | prepareExpression(...) : XQPreparedExpression | semmle.label | prepareExpression(...) : XQPreparedExpression |
| XQueryInjection.java:27:35:27:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:41:37:41:65 | prepareExpression(...) : XQPreparedExpression | semmle.label | prepareExpression(...) : XQPreparedExpression |
| XQueryInjection.java:42:35:42:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:53:37:53:64 | prepareExpression(...) : XQPreparedExpression | semmle.label | prepareExpression(...) : XQPreparedExpression |
| XQueryInjection.java:54:35:54:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:66:37:66:62 | prepareExpression(...) : XQPreparedExpression | semmle.label | prepareExpression(...) : XQPreparedExpression |
| XQueryInjection.java:67:35:67:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:42:23:42:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| XQueryInjection.java:47:35:47:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:55:23:55:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| XQueryInjection.java:60:53:60:57 | query | semmle.label | query |
| XQueryInjection.java:68:32:68:59 | nameStr : String | semmle.label | nameStr : String |
| XQueryInjection.java:73:35:73:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:80:33:80:60 | nameStr : String | semmle.label | nameStr : String |
| XQueryInjection.java:85:53:85:57 | query | semmle.label | query |
| XQueryInjection.java:93:28:93:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
| XQueryInjection.java:97:35:97:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:105:28:105:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
| XQueryInjection.java:109:53:109:56 | name | semmle.label | name |
| XQueryInjection.java:117:28:117:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
| XQueryInjection.java:122:35:122:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:130:28:130:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
| XQueryInjection.java:135:53:135:54 | br | semmle.label | br |
#select
| XQueryInjection.java:27:35:27:38 | xqpe | XQueryInjection.java:26:37:26:65 | prepareExpression(...) : XQPreparedExpression | XQueryInjection.java:27:35:27:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:26:37:26:65 | prepareExpression(...) | this user input |
| XQueryInjection.java:42:35:42:38 | xqpe | XQueryInjection.java:41:37:41:65 | prepareExpression(...) : XQPreparedExpression | XQueryInjection.java:42:35:42:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:41:37:41:65 | prepareExpression(...) | this user input |
| XQueryInjection.java:54:35:54:38 | xqpe | XQueryInjection.java:53:37:53:64 | prepareExpression(...) : XQPreparedExpression | XQueryInjection.java:54:35:54:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:53:37:53:64 | prepareExpression(...) | this user input |
| XQueryInjection.java:67:35:67:38 | xqpe | XQueryInjection.java:66:37:66:62 | prepareExpression(...) : XQPreparedExpression | XQueryInjection.java:67:35:67:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:66:37:66:62 | prepareExpression(...) | this user input |
| XQueryInjection.java:47:35:47:38 | xqpe | XQueryInjection.java:42:23:42:50 | getParameter(...) : String | XQueryInjection.java:47:35:47:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:42:23:42:50 | getParameter(...) | this user input |
| XQueryInjection.java:60:53:60:57 | query | XQueryInjection.java:55:23:55:50 | getParameter(...) : String | XQueryInjection.java:60:53:60:57 | query | XQuery query might include code from $@. | XQueryInjection.java:55:23:55:50 | getParameter(...) | this user input |
| XQueryInjection.java:73:35:73:38 | xqpe | XQueryInjection.java:68:32:68:59 | nameStr : String | XQueryInjection.java:73:35:73:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:68:32:68:59 | nameStr | this user input |
| XQueryInjection.java:85:53:85:57 | query | XQueryInjection.java:80:33:80:60 | nameStr : String | XQueryInjection.java:85:53:85:57 | query | XQuery query might include code from $@. | XQueryInjection.java:80:33:80:60 | nameStr | this user input |
| XQueryInjection.java:97:35:97:38 | xqpe | XQueryInjection.java:93:28:93:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:97:35:97:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:93:28:93:51 | getInputStream(...) | this user input |
| XQueryInjection.java:109:53:109:56 | name | XQueryInjection.java:105:28:105:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:109:53:109:56 | name | XQuery query might include code from $@. | XQueryInjection.java:105:28:105:51 | getInputStream(...) | this user input |
| XQueryInjection.java:122:35:122:38 | xqpe | XQueryInjection.java:117:28:117:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:122:35:122:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:117:28:117:51 | getInputStream(...) | this user input |
| XQueryInjection.java:135:53:135:54 | br | XQueryInjection.java:130:28:130:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:135:53:135:54 | br | XQuery query might include code from $@. | XQueryInjection.java:130:28:130:51 | getInputStream(...) | this user input |

View File

@@ -6,6 +6,7 @@ import javax.xml.namespace.QName;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQExpression;
import javax.xml.xquery.XQItemType;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQResultSequence;
@@ -17,6 +18,25 @@ import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class XQueryInjection {
public static void main(String[] args) throws Exception {
XQDataSource xqds = new SaxonXQDataSource();
XQConnection conn;
try {
String name = "admin";
String query = "declare variable $name as xs:string external;"
+ " for $user in doc(\"users.xml\")/Users/User[name=$name] return $user/password";
conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
expr.bindString(new QName("name"), name, conn.createAtomicType(XQItemType.XQBASETYPE_STRING));
XQResultSequence result = expr.executeQuery(query);
while (result.next()){
System.out.println(result.getItemAsString(null));
}
} catch (XQException e) {
e.printStackTrace();
}
}
@RequestMapping
public void testRequestbad(HttpServletRequest request) throws Exception {
String name = request.getParameter("name");
@@ -28,16 +48,27 @@ public class XQueryInjection {
while (result.next()){
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testRequestbad1(HttpServletRequest request) throws Exception {
String name = request.getParameter("name");
XQDataSource xqds = new SaxonXQDataSource();
String query = "for $user in doc(\"users.xml\")/Users/User[name='" + name + "'] return $user/password";
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
XQResultSequence result = expr.executeQuery(query);
while (result.next()){
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testStringtbad(@RequestParam String nameStr) throws XQException {
String name = nameStr;
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
String query = "for $user in doc(\"users.xml\")/Users/User[name='" + name + "'] return $user/password";
String query = "for $user in doc(\"users.xml\")/Users/User[name='" + nameStr + "'] return $user/password";
XQPreparedExpression xqpe = conn.prepareExpression(query);
XQResultSequence result = xqpe.executeQuery();
while (result.next()){
@@ -45,6 +76,18 @@ public class XQueryInjection {
}
}
@RequestMapping
public void testStringtbad1(@RequestParam String nameStr) throws XQException {
XQDataSource xqds = new SaxonXQDataSource();
String query = "for $user in doc(\"users.xml\")/Users/User[name='" + nameStr + "'] return $user/password";
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
XQResultSequence result = expr.executeQuery(query);
while (result.next()){
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testInputStreambad(HttpServletRequest request) throws Exception {
InputStream name = request.getInputStream();
@@ -57,6 +100,18 @@ public class XQueryInjection {
}
}
@RequestMapping
public void testInputStreambad1(HttpServletRequest request) throws Exception {
InputStream name = request.getInputStream();
XQDataSource xqds = new SaxonXQDataSource();
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
XQResultSequence result = expr.executeQuery(name);
while (result.next()){
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testReaderbad(HttpServletRequest request) throws Exception {
InputStream name = request.getInputStream();
@@ -70,6 +125,19 @@ public class XQueryInjection {
}
}
@RequestMapping
public void testReaderbad1(HttpServletRequest request) throws Exception {
InputStream name = request.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(name));
XQDataSource xqds = new SaxonXQDataSource();
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
XQResultSequence result = expr.executeQuery(br);
while (result.next()){
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void good(HttpServletRequest request) throws XQException {
String name = request.getParameter("name");
@@ -84,4 +152,19 @@ public class XQueryInjection {
System.out.println(result.getItemAsString(null));
}
}
}
@RequestMapping
public void good1(HttpServletRequest request) throws XQException {
String name = request.getParameter("name");
String query = "declare variable $name as xs:string external;"
+ " for $user in doc(\"users.xml\")/Users/User[name=$name] return $user/password";
XQDataSource xqds = new SaxonXQDataSource();
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
expr.bindString(new QName("name"), name, conn.createAtomicType(XQItemType.XQBASETYPE_STRING));
XQResultSequence result = expr.executeQuery(query);
while (result.next()){
System.out.println(result.getItemAsString(null));
}
}
}

View File

@@ -4,6 +4,8 @@ import java.io.InputStream;
import java.io.Reader;
public interface XQConnection extends XQDataFactory {
XQExpression createExpression() throws XQException;
XQPreparedExpression prepareExpression(String var1) throws XQException;

View File

@@ -0,0 +1,25 @@
package javax.xml.xquery;
import java.io.InputStream;
import java.io.Reader;
public interface XQExpression extends XQDynamicContext {
void cancel() throws XQException;
boolean isClosed();
void close() throws XQException;
void executeCommand(String var1) throws XQException;
void executeCommand(Reader var1) throws XQException;
XQResultSequence executeQuery(String var1) throws XQException;
XQResultSequence executeQuery(Reader var1) throws XQException;
XQResultSequence executeQuery(InputStream var1) throws XQException;
XQStaticContext getStaticContext() throws XQException;
}

View File

@@ -15,6 +15,10 @@ public class SaxonXQConnection extends SaxonXQDataFactory implements XQConnecti
SaxonXQConnection(SaxonXQDataSource dataSource) {
}
public XQExpression createExpression() throws XQException {
return null;
}
public XQPreparedExpression prepareExpression(InputStream xquery) throws XQException {
return null;
}