mirror of
https://github.com/github/codeql.git
synced 2026-05-02 20:25:13 +02:00
Merge pull request #4994 from haby0/main
Java: CWE-652: Improper Neutralization of Data within XQuery Expressions ('XQuery Injection')
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
@@ -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) }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
edges
|
||||
| XQueryInjection.java:45:23:45:50 | getParameter(...) : String | XQueryInjection.java:51:35:51:38 | xqpe |
|
||||
| XQueryInjection.java:59:23:59:50 | getParameter(...) : String | XQueryInjection.java:65:53:65:57 | query |
|
||||
| XQueryInjection.java:73:32:73:59 | nameStr : String | XQueryInjection.java:79:35:79:38 | xqpe |
|
||||
| XQueryInjection.java:86:33:86:60 | nameStr : String | XQueryInjection.java:92:53:92:57 | query |
|
||||
| XQueryInjection.java:100:28:100:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:104:35:104:38 | xqpe |
|
||||
| XQueryInjection.java:112:28:112:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:116:53:116:56 | name |
|
||||
| XQueryInjection.java:124:28:124:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:129:35:129:38 | xqpe |
|
||||
| XQueryInjection.java:137:28:137:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:142:53:142:54 | br |
|
||||
| XQueryInjection.java:150:23:150:50 | getParameter(...) : String | XQueryInjection.java:155:29:155:32 | name |
|
||||
| XQueryInjection.java:157:26:157:49 | getInputStream(...) : ServletInputStream | XQueryInjection.java:159:29:159:30 | br |
|
||||
nodes
|
||||
| XQueryInjection.java:45:23:45:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| XQueryInjection.java:51:35:51:38 | xqpe | semmle.label | xqpe |
|
||||
| XQueryInjection.java:59:23:59:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| XQueryInjection.java:65:53:65:57 | query | semmle.label | query |
|
||||
| XQueryInjection.java:73:32:73:59 | nameStr : String | semmle.label | nameStr : String |
|
||||
| XQueryInjection.java:79:35:79:38 | xqpe | semmle.label | xqpe |
|
||||
| XQueryInjection.java:86:33:86:60 | nameStr : String | semmle.label | nameStr : String |
|
||||
| XQueryInjection.java:92:53:92:57 | query | semmle.label | query |
|
||||
| XQueryInjection.java:100:28:100:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
|
||||
| XQueryInjection.java:104:35:104:38 | xqpe | semmle.label | xqpe |
|
||||
| XQueryInjection.java:112:28:112:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
|
||||
| XQueryInjection.java:116:53:116:56 | name | semmle.label | name |
|
||||
| XQueryInjection.java:124:28:124:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
|
||||
| XQueryInjection.java:129:35:129:38 | xqpe | semmle.label | xqpe |
|
||||
| XQueryInjection.java:137:28:137:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
|
||||
| XQueryInjection.java:142:53:142:54 | br | semmle.label | br |
|
||||
| XQueryInjection.java:150:23:150:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| XQueryInjection.java:155:29:155:32 | name | semmle.label | name |
|
||||
| XQueryInjection.java:157:26:157:49 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
|
||||
| XQueryInjection.java:159:29:159:30 | br | semmle.label | br |
|
||||
#select
|
||||
| XQueryInjection.java:51:35:51:38 | xqpe | XQueryInjection.java:45:23:45:50 | getParameter(...) : String | XQueryInjection.java:51:35:51:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:45:23:45:50 | getParameter(...) | this user input |
|
||||
| XQueryInjection.java:65:53:65:57 | query | XQueryInjection.java:59:23:59:50 | getParameter(...) : String | XQueryInjection.java:65:53:65:57 | query | XQuery query might include code from $@. | XQueryInjection.java:59:23:59:50 | getParameter(...) | this user input |
|
||||
| XQueryInjection.java:79:35:79:38 | xqpe | XQueryInjection.java:73:32:73:59 | nameStr : String | XQueryInjection.java:79:35:79:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:73:32:73:59 | nameStr | this user input |
|
||||
| XQueryInjection.java:92:53:92:57 | query | XQueryInjection.java:86:33:86:60 | nameStr : String | XQueryInjection.java:92:53:92:57 | query | XQuery query might include code from $@. | XQueryInjection.java:86:33:86:60 | nameStr | this user input |
|
||||
| XQueryInjection.java:104:35:104:38 | xqpe | XQueryInjection.java:100:28:100:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:104:35:104:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:100:28:100:51 | getInputStream(...) | this user input |
|
||||
| XQueryInjection.java:116:53:116:56 | name | XQueryInjection.java:112:28:112:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:116:53:116:56 | name | XQuery query might include code from $@. | XQueryInjection.java:112:28:112:51 | getInputStream(...) | this user input |
|
||||
| XQueryInjection.java:129:35:129:38 | xqpe | XQueryInjection.java:124:28:124:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:129:35:129:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:124:28:124:51 | getInputStream(...) | this user input |
|
||||
| XQueryInjection.java:142:53:142:54 | br | XQueryInjection.java:137:28:137:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:142:53:142:54 | br | XQuery query might include code from $@. | XQueryInjection.java:137:28:137:51 | getInputStream(...) | this user input |
|
||||
| XQueryInjection.java:155:29:155:32 | name | XQueryInjection.java:150:23:150:50 | getParameter(...) : String | XQueryInjection.java:155:29:155:32 | name | XQuery query might include code from $@. | XQueryInjection.java:150:23:150:50 | getParameter(...) | this user input |
|
||||
| XQueryInjection.java:159:29:159:30 | br | XQueryInjection.java:157:26:157:49 | getInputStream(...) : ServletInputStream | XQueryInjection.java:159:29:159:30 | br | XQuery query might include code from $@. | XQueryInjection.java:157:26:157:49 | getInputStream(...) | this user input |
|
||||
@@ -0,0 +1,195 @@
|
||||
package com.vuln.v2.controller;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
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.XQExpression;
|
||||
import javax.xml.xquery.XQItemType;
|
||||
import javax.xml.xquery.XQPreparedExpression;
|
||||
import javax.xml.xquery.XQResultSequence;
|
||||
import net.sf.saxon.xqj.SaxonXQDataSource;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
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");
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@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 {
|
||||
XQDataSource ds = new SaxonXQDataSource();
|
||||
XQConnection conn = ds.getConnection();
|
||||
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()) {
|
||||
System.out.println(result.getItemAsString(null));
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
XQDataSource ds = new SaxonXQDataSource();
|
||||
XQConnection conn = ds.getConnection();
|
||||
XQPreparedExpression xqpe = conn.prepareExpression(name);
|
||||
XQResultSequence result = xqpe.executeQuery();
|
||||
while (result.next()) {
|
||||
System.out.println(result.getItemAsString(null));
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(name));
|
||||
XQDataSource ds = new SaxonXQDataSource();
|
||||
XQConnection conn = ds.getConnection();
|
||||
XQPreparedExpression xqpe = conn.prepareExpression(br);
|
||||
XQResultSequence result = xqpe.executeQuery();
|
||||
while (result.next()) {
|
||||
System.out.println(result.getItemAsString(null));
|
||||
}
|
||||
}
|
||||
|
||||
@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 testExecuteCommandbad(HttpServletRequest request) throws Exception {
|
||||
String name = request.getParameter("name");
|
||||
XQDataSource xqds = new SaxonXQDataSource();
|
||||
XQConnection conn = xqds.getConnection();
|
||||
XQExpression expr = conn.createExpression();
|
||||
//bad code
|
||||
expr.executeCommand(name);
|
||||
//bad code
|
||||
InputStream is = request.getInputStream();
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
expr.executeCommand(br);
|
||||
expr.close();
|
||||
}
|
||||
|
||||
@RequestMapping
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-652/XQueryInjection.ql
|
||||
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/apache-http-4.4.13/:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/saxon-xqj-9.x/:${testdir}/../../../../stubs/springframework-5.2.3/
|
||||
@@ -0,0 +1,21 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
public interface XQConnection extends XQDataFactory {
|
||||
|
||||
XQExpression createExpression() throws XQException;
|
||||
|
||||
XQPreparedExpression prepareExpression(String var1) throws XQException;
|
||||
|
||||
XQPreparedExpression prepareExpression(String var1, XQStaticContext var2) throws XQException;
|
||||
|
||||
XQPreparedExpression prepareExpression(Reader var1) throws XQException;
|
||||
|
||||
XQPreparedExpression prepareExpression(Reader var1, XQStaticContext var2) throws XQException;
|
||||
|
||||
XQPreparedExpression prepareExpression(InputStream var1) throws XQException;
|
||||
|
||||
XQPreparedExpression prepareExpression(InputStream var1, XQStaticContext var2) throws XQException;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
public interface XQDataFactory {
|
||||
XQItemType createAtomicType(int var1) throws XQException;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
public interface XQDataSource {
|
||||
XQConnection getConnection() throws XQException;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
public interface XQDynamicContext {
|
||||
void bindString(QName var1, String var2, XQItemType var3) throws XQException;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
public class XQException extends Exception {}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
public interface XQItemAccessor {
|
||||
String getItemAsString(Properties var1) throws XQException;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
public interface XQItemType extends XQSequenceType {
|
||||
int XQITEMKIND_ATOMIC = 1;
|
||||
int XQITEMKIND_ATTRIBUTE = 2;
|
||||
int XQITEMKIND_COMMENT = 3;
|
||||
int XQITEMKIND_DOCUMENT = 4;
|
||||
int XQITEMKIND_DOCUMENT_ELEMENT = 5;
|
||||
int XQITEMKIND_DOCUMENT_SCHEMA_ELEMENT = 6;
|
||||
int XQITEMKIND_ELEMENT = 7;
|
||||
int XQITEMKIND_ITEM = 8;
|
||||
int XQITEMKIND_NODE = 9;
|
||||
int XQITEMKIND_PI = 10;
|
||||
int XQITEMKIND_TEXT = 11;
|
||||
int XQITEMKIND_SCHEMA_ELEMENT = 12;
|
||||
int XQITEMKIND_SCHEMA_ATTRIBUTE = 13;
|
||||
int XQBASETYPE_UNTYPED = 1;
|
||||
int XQBASETYPE_ANYTYPE = 2;
|
||||
int XQBASETYPE_ANYSIMPLETYPE = 3;
|
||||
int XQBASETYPE_ANYATOMICTYPE = 4;
|
||||
int XQBASETYPE_UNTYPEDATOMIC = 5;
|
||||
int XQBASETYPE_DAYTIMEDURATION = 6;
|
||||
int XQBASETYPE_YEARMONTHDURATION = 7;
|
||||
int XQBASETYPE_ANYURI = 8;
|
||||
int XQBASETYPE_BASE64BINARY = 9;
|
||||
int XQBASETYPE_BOOLEAN = 10;
|
||||
int XQBASETYPE_DATE = 11;
|
||||
int XQBASETYPE_INT = 12;
|
||||
int XQBASETYPE_INTEGER = 13;
|
||||
int XQBASETYPE_SHORT = 14;
|
||||
int XQBASETYPE_LONG = 15;
|
||||
int XQBASETYPE_DATETIME = 16;
|
||||
int XQBASETYPE_DECIMAL = 17;
|
||||
int XQBASETYPE_DOUBLE = 18;
|
||||
int XQBASETYPE_DURATION = 19;
|
||||
int XQBASETYPE_FLOAT = 20;
|
||||
int XQBASETYPE_GDAY = 21;
|
||||
int XQBASETYPE_GMONTH = 22;
|
||||
int XQBASETYPE_GMONTHDAY = 23;
|
||||
int XQBASETYPE_GYEAR = 24;
|
||||
int XQBASETYPE_GYEARMONTH = 25;
|
||||
int XQBASETYPE_HEXBINARY = 26;
|
||||
int XQBASETYPE_NOTATION = 27;
|
||||
int XQBASETYPE_QNAME = 28;
|
||||
int XQBASETYPE_STRING = 29;
|
||||
int XQBASETYPE_TIME = 30;
|
||||
int XQBASETYPE_BYTE = 31;
|
||||
int XQBASETYPE_NONPOSITIVE_INTEGER = 32;
|
||||
int XQBASETYPE_NONNEGATIVE_INTEGER = 33;
|
||||
int XQBASETYPE_NEGATIVE_INTEGER = 34;
|
||||
int XQBASETYPE_POSITIVE_INTEGER = 35;
|
||||
int XQBASETYPE_UNSIGNED_LONG = 36;
|
||||
int XQBASETYPE_UNSIGNED_INT = 37;
|
||||
int XQBASETYPE_UNSIGNED_SHORT = 38;
|
||||
int XQBASETYPE_UNSIGNED_BYTE = 39;
|
||||
int XQBASETYPE_NORMALIZED_STRING = 40;
|
||||
int XQBASETYPE_TOKEN = 41;
|
||||
int XQBASETYPE_LANGUAGE = 42;
|
||||
int XQBASETYPE_NAME = 43;
|
||||
int XQBASETYPE_NCNAME = 44;
|
||||
int XQBASETYPE_NMTOKEN = 45;
|
||||
int XQBASETYPE_ID = 46;
|
||||
int XQBASETYPE_IDREF = 47;
|
||||
int XQBASETYPE_ENTITY = 48;
|
||||
int XQBASETYPE_IDREFS = 49;
|
||||
int XQBASETYPE_ENTITIES = 50;
|
||||
int XQBASETYPE_NMTOKENS = 51;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
public interface XQPreparedExpression extends XQDynamicContext {
|
||||
XQResultSequence executeQuery() throws XQException;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
public interface XQResultSequence extends XQSequence {}
|
||||
@@ -0,0 +1,5 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
public interface XQSequence extends XQItemAccessor {
|
||||
boolean next() throws XQException;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
public interface XQSequenceType {}
|
||||
@@ -0,0 +1,3 @@
|
||||
package javax.xml.xquery;
|
||||
|
||||
public interface XQStaticContext {}
|
||||
@@ -0,0 +1,6 @@
|
||||
package net.sf.saxon;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class Configuration implements Serializable, SourceResolver {}
|
||||
@@ -0,0 +1,3 @@
|
||||
package net.sf.saxon;
|
||||
|
||||
public interface SourceResolver {}
|
||||
@@ -0,0 +1,3 @@
|
||||
package net.sf.saxon.xqj;
|
||||
|
||||
public abstract class Closable {}
|
||||
@@ -0,0 +1,46 @@
|
||||
package net.sf.saxon.xqj;
|
||||
|
||||
import java.io.Reader;
|
||||
import net.sf.saxon.Configuration;
|
||||
import javax.xml.xquery.XQConnection;
|
||||
import javax.xml.xquery.XQPreparedExpression;
|
||||
import javax.xml.xquery.XQException;
|
||||
import javax.xml.xquery.XQExpression;
|
||||
import javax.xml.xquery.XQStaticContext;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class SaxonXQConnection extends SaxonXQDataFactory implements XQConnection {
|
||||
|
||||
private SaxonXQStaticContext staticContext;
|
||||
|
||||
SaxonXQConnection(SaxonXQDataSource dataSource) {
|
||||
}
|
||||
|
||||
public XQExpression createExpression() throws XQException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public XQPreparedExpression prepareExpression(InputStream xquery) throws XQException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public XQPreparedExpression prepareExpression(InputStream xquery, XQStaticContext properties) throws XQException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public XQPreparedExpression prepareExpression(Reader xquery) throws XQException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public XQPreparedExpression prepareExpression(Reader xquery, XQStaticContext properties){
|
||||
return null;
|
||||
}
|
||||
|
||||
public XQPreparedExpression prepareExpression(String xquery) throws XQException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public XQPreparedExpression prepareExpression(String xquery, XQStaticContext properties) throws XQException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package net.sf.saxon.xqj;
|
||||
|
||||
import javax.xml.xquery.XQException;
|
||||
import javax.xml.xquery.XQDataFactory;
|
||||
import javax.xml.xquery.XQItemType;
|
||||
|
||||
public abstract class SaxonXQDataFactory extends Closable implements XQDataFactory {
|
||||
public XQItemType createAtomicType(int baseType) throws XQException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package net.sf.saxon.xqj;
|
||||
|
||||
import javax.xml.xquery.XQDataSource;
|
||||
import javax.xml.xquery.XQException;
|
||||
import javax.xml.xquery.XQConnection;
|
||||
|
||||
public class SaxonXQDataSource implements XQDataSource {
|
||||
|
||||
public XQConnection getConnection() throws XQException {
|
||||
return new SaxonXQConnection(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package net.sf.saxon.xqj;
|
||||
|
||||
import javax.xml.xquery.XQStaticContext;
|
||||
|
||||
public class SaxonXQStaticContext implements XQStaticContext {}
|
||||
Reference in New Issue
Block a user