move the query to experimental folder

This commit is contained in:
haby0
2021-03-05 14:38:04 +08:00
parent 2c96e6cf96
commit ecdadd1826
5 changed files with 1 additions and 1 deletions

View File

@@ -0,0 +1,70 @@
import javax.servlet.http.HttpServletRequest;
import javax.xml.namespace.QName;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQItemType;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQResultSequence;
import net.sf.saxon.xqj.SaxonXQDataSource;
public void bad(HttpServletRequest request) throws XQException {
String name = request.getParameter("name");
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
String query = "for $user in doc(\"users.xml\")/Users/User[name='" + name + "'] return $user/password";
XQPreparedExpression xqpe = conn.prepareExpression(query);
XQResultSequence result = xqpe.executeQuery();
while (result.next()){
System.out.println(result.getItemAsString(null));
}
}
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 bad2(HttpServletRequest request) throws XQException {
String name = request.getParameter("name");
XQDataSource xqds = new SaxonXQDataSource();
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
//bad code
expr.executeCommand(name);
}
public void good(HttpServletRequest request) throws XQException {
String name = request.getParameter("name");
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
String query = "declare variable $name as xs:string external;"
+ " for $user in doc(\"users.xml\")/Users/User[name=$name] return $user/password";
XQPreparedExpression xqpe = conn.prepareExpression(query);
xqpe.bindString(new QName("name"), name, conn.createAtomicType(XQItemType.XQBASETYPE_STRING));
XQResultSequence result = xqpe.executeQuery();
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

@@ -0,0 +1,33 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>The software uses external input to dynamically construct an XQuery expression which is then used to retrieve data from an XML database.
However, the input is not neutralized, or is incorrectly neutralized, which allows an attacker to control the structure of the query.</p>
</overview>
<recommendation>
<p>Use parameterized queries. This will help ensure the program retains control of the query structure.</p>
</recommendation>
<example>
<p>The following example compares building a query by string concatenation (bad) vs. using <code>bindString</code> to parameterize the query (good).</p>
<sample src="XQueryInjection.java" />
</example>
<references>
<li>Balisage:
<a href="https://www.balisage.net/Proceedings/vol7/html/Vlist02/BalisageVol7-Vlist02.html">XQuery Injection</a>.</li>
<!-- LocalWords: CWE
-->
</references>
</qhelp>

View File

@@ -0,0 +1,43 @@
/**
* @name XQuery query built from user-controlled sources
* @description Building an XQuery query from user-controlled sources is vulnerable to insertion of
* malicious XQuery code by the user.
* @kind path-problem
* @problem.severity error
* @precision high
* @id java/xquery-injection
* @tags security
* external/cwe/cwe-652
*/
import java
import semmle.code.java.dataflow.FlowSources
import XQueryInjectionLib
import DataFlow::PathGraph
/**
* A taint-tracking configuration tracing flow from remote sources, through an XQuery parser, to its eventual execution.
*/
class XQueryInjectionConfig extends TaintTracking::Configuration {
XQueryInjectionConfig() { this = "XQueryInjectionConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(XQueryPreparedExecuteCall xpec).getPreparedExpression() or
sink.asExpr() = any(XQueryExecuteCall xec).getExecuteQueryArgument() or
sink.asExpr() = any(XQueryExecuteCommandCall xecc).getExecuteCommandArgument()
}
/**
* Holds if taint from the input `pred` to a `prepareExpression` call flows to the returned prepared expression `succ`.
*/
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(XQueryParserCall parser | pred.asExpr() = parser.getInput() and succ.asExpr() = parser)
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, XQueryInjectionConfig conf
where conf.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "XQuery query might include code from $@.", source.getNode(),
"this user input"

View File

@@ -0,0 +1,68 @@
import java
/** A call to `XQConnection.prepareExpression`. */
class XQueryParserCall extends MethodAccess {
XQueryParserCall() {
exists(Method m |
this.getMethod() = m and
m.getDeclaringType()
.getASourceSupertype*()
.hasQualifiedName("javax.xml.xquery", "XQConnection") and
m.hasName("prepareExpression")
)
}
/**
* Returns the first parameter of the `prepareExpression` method, which provides
* the string, stream or reader to be compiled into a prepared expression.
*/
Expr getInput() { result = this.getArgument(0) }
}
/** A call to `XQPreparedExpression.executeQuery`. */
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) }
}
/** A call to `XQExpression.executeCommand`. */
class XQueryExecuteCommandCall extends MethodAccess {
XQueryExecuteCommandCall() {
exists(Method m |
this.getMethod() = m and
m.hasName("executeCommand") and
m.getDeclaringType()
.getASourceSupertype*()
.hasQualifiedName("javax.xml.xquery", "XQExpression")
)
}
/** Return this execute command argument. */
Expr getExecuteCommandArgument() { result = this.getArgument(0) }
}