Modify according to suggestions

This commit is contained in:
haby0
2021-12-01 11:57:57 +08:00
parent db04a0dadf
commit 08be8edbce
16 changed files with 158 additions and 262 deletions

View File

@@ -35,9 +35,9 @@ class IbatisConfiguration extends RefType {
*/ */
class IbatisConfigurationGetVariablesMethod extends Method { class IbatisConfigurationGetVariablesMethod extends Method {
IbatisConfigurationGetVariablesMethod() { IbatisConfigurationGetVariablesMethod() {
getDeclaringType() instanceof IbatisConfiguration and this.getDeclaringType() instanceof IbatisConfiguration and
hasName("getVariables") and this.hasName("getVariables") and
getNumberOfParameters() = 0 this.getNumberOfParameters() = 0
} }
} }
@@ -45,114 +45,62 @@ class IbatisConfigurationGetVariablesMethod extends Method {
* An annotation type that identifies Ibatis select. * An annotation type that identifies Ibatis select.
*/ */
private class IbatisSelectAnnotationType extends AnnotationType { private class IbatisSelectAnnotationType extends AnnotationType {
IbatisSelectAnnotationType() { IbatisSelectAnnotationType() { this.hasQualifiedName("org.apache.ibatis.annotations", "Select") }
this.hasQualifiedName("org.apache.ibatis.annotations", "Select") or
this.getAnAnnotation().getType() instanceof IbatisSelectAnnotationType
}
} }
/** /**
* An annotation type that identifies Ibatis delete. * An annotation type that identifies Ibatis delete.
*/ */
private class IbatisDeleteAnnotationType extends AnnotationType { private class IbatisDeleteAnnotationType extends AnnotationType {
IbatisDeleteAnnotationType() { IbatisDeleteAnnotationType() { this.hasQualifiedName("org.apache.ibatis.annotations", "Delete") }
this.hasQualifiedName("org.apache.ibatis.annotations", "Delete") or
this.getAnAnnotation().getType() instanceof IbatisDeleteAnnotationType
}
} }
/** /**
* An annotation type that identifies Ibatis insert. * An annotation type that identifies Ibatis insert.
*/ */
private class IbatisInsertAnnotationType extends AnnotationType { private class IbatisInsertAnnotationType extends AnnotationType {
IbatisInsertAnnotationType() { IbatisInsertAnnotationType() { this.hasQualifiedName("org.apache.ibatis.annotations", "Insert") }
this.hasQualifiedName("org.apache.ibatis.annotations", "Insert") or
this.getAnAnnotation().getType() instanceof IbatisInsertAnnotationType
}
} }
/** /**
* An annotation type that identifies Ibatis update. * An annotation type that identifies Ibatis update.
*/ */
private class IbatisUpdateAnnotationType extends AnnotationType { private class IbatisUpdateAnnotationType extends AnnotationType {
IbatisUpdateAnnotationType() { IbatisUpdateAnnotationType() { this.hasQualifiedName("org.apache.ibatis.annotations", "Update") }
this.hasQualifiedName("org.apache.ibatis.annotations", "Update") or
this.getAnAnnotation().getType() instanceof IbatisUpdateAnnotationType
}
} }
/** /**
* Ibatis sql operation annotation. * Ibatis sql operation annotation.
*/ */
abstract class IbatisSqlOperationAnnotation extends Annotation { class IbatisSqlOperationAnnotation extends Annotation {
abstract string getSqlValue(); IbatisSqlOperationAnnotation() {
} this.getType() instanceof IbatisSelectAnnotationType or
this.getType() instanceof IbatisDeleteAnnotationType or
this.getType() instanceof IbatisInsertAnnotationType or
this.getType() instanceof IbatisUpdateAnnotationType
}
/** /**
* A `@org.apache.ibatis.annotations.Select` annotation. * Get the SQL statement string.
*/ */
private class IbatisSelectAnnotation extends IbatisSqlOperationAnnotation { string getSqlValue() {
IbatisSelectAnnotation() { this.getType() instanceof IbatisSelectAnnotationType }
string getSelectValue() {
result = this.getValue("value").(CompileTimeConstantExpr).getStringValue() or result = this.getValue("value").(CompileTimeConstantExpr).getStringValue() or
result = result =
this.getValue("value").(ArrayInit).getInit(_).(CompileTimeConstantExpr).getStringValue() this.getValue("value").(ArrayInit).getInit(_).(CompileTimeConstantExpr).getStringValue()
} }
override string getSqlValue() { result = getSelectValue() }
} }
/** /**
* A `@org.apache.ibatis.annotations.Delete` annotation. * Methods annotated with `@org.apache.ibatis.annotations.Select` or `@org.apache.ibatis.annotations.Delete`
* or `@org.apache.ibatis.annotations.Update` or `@org.apache.ibatis.annotations.Insert`.
*/ */
private class IbatisDeleteAnnotation extends IbatisSqlOperationAnnotation { class MyBatisSqlOperationAnnotationMethod extends Method {
IbatisDeleteAnnotation() { this.getType() instanceof IbatisDeleteAnnotationType } MyBatisSqlOperationAnnotationMethod() {
this.getAnAnnotation() instanceof IbatisSqlOperationAnnotation
string getDeleteValue() {
result = this.getValue("value").(CompileTimeConstantExpr).getStringValue() or
result =
this.getValue("value").(ArrayInit).getInit(_).(CompileTimeConstantExpr).getStringValue()
}
override string getSqlValue() { result = getDeleteValue() }
}
/**
* A `@org.apache.ibatis.annotations.Insert` annotation.
*/
private class IbatisInsertAnnotation extends IbatisSqlOperationAnnotation {
IbatisInsertAnnotation() { this.getType() instanceof IbatisInsertAnnotationType }
string getInsertValue() {
result = this.getValue("value").(CompileTimeConstantExpr).getStringValue() or
result =
this.getValue("value").(ArrayInit).getInit(_).(CompileTimeConstantExpr).getStringValue()
}
override string getSqlValue() { result = getInsertValue() }
}
/**
* A `@org.apache.ibatis.annotations.Update` annotation.
*/
private class IbatisUpdateAnnotation extends IbatisSqlOperationAnnotation {
IbatisUpdateAnnotation() { this.getType() instanceof IbatisUpdateAnnotationType }
string getUpdateValue() {
result = this.getValue("value").(CompileTimeConstantExpr).getStringValue() or
result =
this.getValue("value").(ArrayInit).getInit(_).(CompileTimeConstantExpr).getStringValue()
}
override string getSqlValue() { result = getUpdateValue() }
}
// Mybatis uses sql operation to annotate the method of interacting with the database.
class MybatisSqlOperationAnnotationMethod extends Method {
MybatisSqlOperationAnnotationMethod() {
exists(IbatisSqlOperationAnnotation isoa |
this.getAnAnnotation() = isoa
)
} }
} }
/** The interface `org.apache.ibatis.annotations.Param`. */
class TypeParam extends Interface {
TypeParam() { this.hasQualifiedName("org.apache.ibatis.annotations", "Param") }
}

View File

@@ -4,23 +4,21 @@
"qhelp.dtd"> "qhelp.dtd">
<qhelp> <qhelp>
<overview> <overview>
<p>MyBatis operates the database by using @Select, @Insert, etc. annotations in the method, and can use the $ character <p>MyBatis allows operating the database by annotating a method with the annotations <code>@Select</code>, <code>@Insert</code>, etc. to construct dynamic SQL statements.
to construct dynamic SQL statements. Attackers can modify the meaning of statements or execute arbitrary SQL commands.</p> If the syntax `${param}` is used in those statements, and `param` is a parameter of the annotated method, attackers can exploit this to tamper with the SQL statements or execute arbitrary SQL commands.</p>
</overview> </overview>
<<recommendation> <<recommendation>
<p> <p>
When writing MyBatis mapping statements, try to use the format "#{xxx}". If you have to use parameters When writing MyBatis mapping statements, try to use the syntax <code>#{xxx}</code>. If the syntax <code>${xxx}</code> must be used, any parameters included in it should be sanitized to prevent SQL injection attacks.
such as "${xxx}", you must manually filter to prevent SQL injection attacks.
</p> </p>
</recommendation> </recommendation>
<example> <example>
<p> <p>
The following examples show the bad situation and the good situation respectively. The <code>bad1</code> method uses <code>$(name)</code> The following sample shows a bad and a good example of MyBatis annotations usage. The <code>bad1</code> method uses <code>$(name)</code>
in the <code>@Select</code> annotation to dynamically splice SQL statements, and there is a SQL injection vulnerability. in the <code>@Select</code> annotation to dynamically build a SQL statement, which causes a SQL injection vulnerability.
The good1 method uses the <code>#{name}</code> method in the <code>@Select</code> annotation to splice SQL statements, The <code>good1</code> method uses <code>#{name}</code> in the <code>@Select</code> annotation to to dynamically include the parameter in a SQL statement, which allows the MyBatis framework to handle the sanitization, preventing the vulnerability.
and the MyBatis framework will handle the dangerous characters entered by the user, And did not cause SQL injection vulnerabilities.
</p> </p>
<sample src="MyBatisAnnotationSqlInjection.java" /> <sample src="MyBatisAnnotationSqlInjection.java" />
</example> </example>

View File

@@ -1,12 +1,12 @@
/** /**
* @name MyBatis annotation sql injection * @name SQL injection in MyBatis annotation
* @description Constructing a dynamic SQL statement with input that comes from an * @description Constructing a dynamic SQL statement with input that comes from an
* untrusted source could allow an attacker to modify the statement's * untrusted source could allow an attacker to modify the statement's
* meaning or to execute arbitrary SQL commands. * meaning or to execute arbitrary SQL commands.
* @kind path-problem * @kind path-problem
* @problem.severity error * @problem.severity error
* @precision high * @precision high
* @id java/sql-injection * @id java/mybatis-annotation-sql-injection
* @tags security * @tags security
* external/cwe/cwe-089 * external/cwe/cwe-089
*/ */
@@ -14,7 +14,6 @@
import java import java
import DataFlow::PathGraph import DataFlow::PathGraph
import MyBatisAnnotationSqlInjectionLib import MyBatisAnnotationSqlInjectionLib
import semmle.code.java.security.SanitizerGuard
import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.FlowSources
private class MyBatisAnnotationSqlInjectionConfiguration extends TaintTracking::Configuration { private class MyBatisAnnotationSqlInjectionConfiguration extends TaintTracking::Configuration {
@@ -32,10 +31,6 @@ private class MyBatisAnnotationSqlInjectionConfiguration extends TaintTracking::
node.getType() instanceof NumberType node.getType() instanceof NumberType
} }
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
guard instanceof ContainsSanitizer or guard instanceof EqualsSanitizer
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma | exists(MethodAccess ma |
ma.getMethod().getDeclaringType() instanceof MapType and ma.getMethod().getDeclaringType() instanceof MapType and
@@ -60,5 +55,5 @@ where
cfg.hasFlowPath(source, sink) and cfg.hasFlowPath(source, sink) and
isMybatisAnnotationSqlInjection(sink.getNode(), isoa) isMybatisAnnotationSqlInjection(sink.getNode(), isoa)
select sink.getNode(), source, sink, select sink.getNode(), source, sink,
"MyBatis annotation sql injection might include code from $@ to $@.", source.getNode(), "MyBatis annotation SQL injection might include code from $@ to $@.", source.getNode(),
"this user input", isoa, "this sql operation" "this user input", isoa, "this SQL operation"

View File

@@ -1,3 +1,7 @@
/**
* Provides classes for SQL injection detection in MyBatis annotation.
*/
import java import java
import MyBatisCommonLib import MyBatisCommonLib
import semmle.code.xml.MyBatisMapperXML import semmle.code.xml.MyBatisMapperXML
@@ -7,7 +11,7 @@ import semmle.code.java.frameworks.Properties
/** A sink for MyBatis annotation method call an argument. */ /** A sink for MyBatis annotation method call an argument. */
class MyBatisAnnotationMethodCallAnArgument extends DataFlow::Node { class MyBatisAnnotationMethodCallAnArgument extends DataFlow::Node {
MyBatisAnnotationMethodCallAnArgument() { MyBatisAnnotationMethodCallAnArgument() {
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma | ma.getMethod() = msoam | exists(MyBatisSqlOperationAnnotationMethod msoam, MethodAccess ma | ma.getMethod() = msoam |
ma.getAnArgument() = this.asExpr() ma.getAnArgument() = this.asExpr()
) )
} }
@@ -15,7 +19,7 @@ class MyBatisAnnotationMethodCallAnArgument extends DataFlow::Node {
/** Get the #{...} or ${...} parameters in the Mybatis annotation value. */ /** Get the #{...} or ${...} parameters in the Mybatis annotation value. */
private string getAnMybatiAnnotationSetValue(IbatisSqlOperationAnnotation isoa) { private string getAnMybatiAnnotationSetValue(IbatisSqlOperationAnnotation isoa) {
result = isoa.getSqlValue().trim().regexpFind("(#|\\$)(\\{([^\\}]*\\}))", _, _) result = isoa.getSqlValue().trim().regexpFind("(#|\\$)\\{[^\\}]*\\}", _, _)
} }
predicate isMybatisAnnotationSqlInjection(DataFlow::Node node, IbatisSqlOperationAnnotation isoa) { predicate isMybatisAnnotationSqlInjection(DataFlow::Node node, IbatisSqlOperationAnnotation isoa) {
@@ -27,15 +31,15 @@ predicate isMybatisAnnotationSqlInjection(DataFlow::Node node, IbatisSqlOperatio
// @Select(select id,name from test where name like '%${value}%') // @Select(select id,name from test where name like '%${value}%')
// Test test(String name); // Test test(String name);
// ``` // ```
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma, string res | exists(MyBatisSqlOperationAnnotationMethod msoam, MethodAccess ma, string res |
msoam = ma.getMethod() msoam = ma.getMethod()
| |
msoam.getAnAnnotation() = isoa and msoam.getAnAnnotation() = isoa and
res = getAnMybatiAnnotationSetValue(isoa) and res = getAnMybatiAnnotationSetValue(isoa) and
msoam.getNumberOfParameters() = 1 and msoam.getNumberOfParameters() = 1 and
not ma.getMethod().getAParameter().hasAnnotation() and not ma.getMethod().getAParameter().getAnAnnotation().getType() instanceof TypeParam and
res.matches("%${%}") and res.matches("%${%}") and
not res.matches("${" + getAnMybatisConfigurationVariableKey() + "}") and not res = "${" + getAnMybatisConfigurationVariableKey() + "}" and
ma.getAnArgument() = node.asExpr() ma.getAnArgument() = node.asExpr()
) )
or or
@@ -47,11 +51,11 @@ predicate isMybatisAnnotationSqlInjection(DataFlow::Node node, IbatisSqlOperatio
// @Select(select id,name from test where name like '%${value}%') // @Select(select id,name from test where name like '%${value}%')
// Test test(Map map); // Test test(Map map);
// ``` // ```
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, string res | exists(MyBatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, string res |
msoam = ma.getMethod() msoam = ma.getMethod()
| |
msoam.getAnAnnotation() = isoa and msoam.getAnAnnotation() = isoa and
not ma.getMethod().getParameter(i).hasAnnotation() and not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
( (
ma.getMethod().getParameterType(i) instanceof MapType or ma.getMethod().getParameterType(i) instanceof MapType or
ma.getMethod().getParameterType(i) instanceof ListType or ma.getMethod().getParameterType(i) instanceof ListType or
@@ -59,7 +63,7 @@ predicate isMybatisAnnotationSqlInjection(DataFlow::Node node, IbatisSqlOperatio
) and ) and
res = getAnMybatiAnnotationSetValue(isoa) and res = getAnMybatiAnnotationSetValue(isoa) and
res.matches("%${%}") and res.matches("%${%}") and
not res.matches("${" + getAnMybatisConfigurationVariableKey() + "}") and not res = "${" + getAnMybatisConfigurationVariableKey() + "}" and
ma.getArgument(i) = node.asExpr() ma.getArgument(i) = node.asExpr()
) )
or or
@@ -71,13 +75,13 @@ predicate isMybatisAnnotationSqlInjection(DataFlow::Node node, IbatisSqlOperatio
// @Select(select id,name from test order by ${name,jdbcType=VARCHAR}) // @Select(select id,name from test order by ${name,jdbcType=VARCHAR})
// void test(Test test); // void test(Test test);
// ``` // ```
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, Class c | exists(MyBatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, RefType t |
msoam = ma.getMethod() msoam = ma.getMethod()
| |
msoam.getAnAnnotation() = isoa and msoam.getAnAnnotation() = isoa and
not ma.getMethod().getParameter(i).hasAnnotation() and not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
ma.getMethod().getParameterType(i).getName() = c.getName() and ma.getMethod().getParameterType(i).getName() = t.getName() and
getAnMybatiAnnotationSetValue(isoa).matches("%${" + c.getAField().getName() + "%}") and getAnMybatiAnnotationSetValue(isoa).matches("%${" + t.getAField().getName() + "%}") and
ma.getArgument(i) = node.asExpr() ma.getArgument(i) = node.asExpr()
) )
or or
@@ -89,12 +93,10 @@ predicate isMybatisAnnotationSqlInjection(DataFlow::Node node, IbatisSqlOperatio
// @Select(select id,name from test order by ${orderby,jdbcType=VARCHAR}) // @Select(select id,name from test order by ${orderby,jdbcType=VARCHAR})
// void test(@Param("orderby") String name); // void test(@Param("orderby") String name);
// ``` // ```
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, Annotation annotation | exists(MyBatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, Annotation annotation |
msoam = ma.getMethod() msoam = ma.getMethod() and ma.getMethod().getParameter(i).getAnAnnotation() = annotation
| |
msoam.getAnAnnotation() = isoa and msoam.getAnAnnotation() = isoa and
ma.getMethod().getParameter(i).hasAnnotation() and
ma.getMethod().getParameter(i).getAnAnnotation() = annotation and
annotation.getType() instanceof TypeParam and annotation.getType() instanceof TypeParam and
getAnMybatiAnnotationSetValue(isoa) getAnMybatiAnnotationSetValue(isoa)
.matches("%${" + annotation.getValue("value").(CompileTimeConstantExpr).getStringValue() + .matches("%${" + annotation.getValue("value").(CompileTimeConstantExpr).getStringValue() +
@@ -109,18 +111,18 @@ predicate isMybatisAnnotationSqlInjection(DataFlow::Node node, IbatisSqlOperatio
// @Select(select id,name from test order by ${arg0,jdbcType=VARCHAR}) // @Select(select id,name from test order by ${arg0,jdbcType=VARCHAR})
// void test(String name); // void test(String name);
// ``` // ```
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, string res | exists(MyBatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, string res |
msoam = ma.getMethod() msoam = ma.getMethod()
| |
msoam.getAnAnnotation() = isoa and msoam.getAnAnnotation() = isoa and
not ma.getMethod().getParameter(i).hasAnnotation() and not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
res = getAnMybatiAnnotationSetValue(isoa) and res = getAnMybatiAnnotationSetValue(isoa) and
( (
res.matches("%${param" + (i + 1) + "%}") res.matches("%${param" + (i + 1) + "%}")
or or
res.matches("%${arg" + i + "%}") res.matches("%${arg" + i + "%}")
) and ) and
not res.matches("${" + getAnMybatisConfigurationVariableKey() + "}") and not res = "${" + getAnMybatisConfigurationVariableKey() + "}" and
ma.getArgument(i) = node.asExpr() ma.getArgument(i) = node.asExpr()
) )
} }

View File

@@ -1,3 +1,7 @@
/**
* Provides public classes for MyBatis SQL injection detection.
*/
import java import java
import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.FlowSources
import semmle.code.java.frameworks.MyBatis import semmle.code.java.frameworks.MyBatis
@@ -28,15 +32,10 @@ private class PropertiesFlowConfig extends DataFlow2::Configuration {
string getAnMybatisConfigurationVariableKey() { string getAnMybatisConfigurationVariableKey() {
exists(PropertiesFlowConfig conf, DataFlow::Node n | exists(PropertiesFlowConfig conf, DataFlow::Node n |
propertiesKey(n, result) and propertiesKey(n, result) and
conf.hasFlow(_, n) conf.hasFlowTo(n)
) )
} }
/** The interface `org.apache.ibatis.annotations.Param`. */
class TypeParam extends Interface {
TypeParam() { this.hasQualifiedName("org.apache.ibatis.annotations", "Param") }
}
/** A reference type that extends a parameterization of `java.util.List`. */ /** A reference type that extends a parameterization of `java.util.List`. */
class ListType extends RefType { class ListType extends RefType {
ListType() { ListType() {

View File

@@ -9,8 +9,7 @@
<<recommendation> <<recommendation>
<p> <p>
When writing MyBatis mapping statements, try to use the format "#{xxx}". If you have to use parameters When writing MyBatis mapping statements, try to use the syntax <code>#{xxx}</code>. If the syntax <code>${xxx}</code> must be used, any parameters included in it should be sanitized to prevent SQL injection attacks.
such as "${xxx}", you must manually filter to prevent SQL injection attacks.
</p> </p>
</recommendation> </recommendation>
@@ -18,7 +17,7 @@ such as "${xxx}", you must manually filter to prevent SQL injection attacks.
<p> <p>
The following examples show the bad situation and the good situation respectively. In <code>bad1</code> The following examples show the bad situation and the good situation respectively. In <code>bad1</code>
and <code>bad2</code> and <code>bad3</code> and <code>bad4</code> and <code >bad5</code>, the program and <code>bad2</code> and <code>bad3</code> and <code>bad4</code> and <code >bad5</code>, the program
${ xxx} are dynamic SQL statements, these five examples of SQL injection vulnerabilities. In <code>good1</code>, ${xxx} are dynamic SQL statements, these five examples of SQL injection vulnerabilities. In <code>good1</code>,
the program uses the ${xxx} dynamic feature SQL statement, but there are subtle restrictions on the data, the program uses the ${xxx} dynamic feature SQL statement, but there are subtle restrictions on the data,
and there is no SQL injection vulnerability. and there is no SQL injection vulnerability.
</p> </p>

View File

@@ -1,12 +1,12 @@
/** /**
* @name MyBatis Mapper xml sql injection * @name SQL injection in MyBatis Mapper XML
* @description Constructing a dynamic SQL statement with input that comes from an * @description Constructing a dynamic SQL statement with input that comes from an
* untrusted source could allow an attacker to modify the statement's * untrusted source could allow an attacker to modify the statement's
* meaning or to execute arbitrary SQL commands. * meaning or to execute arbitrary SQL commands.
* @kind path-problem * @kind path-problem
* @problem.severity error * @problem.severity error
* @precision high * @precision high
* @id java/sql-injection * @id java/mybatis-xml-sql-injection
* @tags security * @tags security
* external/cwe/cwe-089 * external/cwe/cwe-089
*/ */
@@ -15,7 +15,6 @@ import java
import DataFlow::PathGraph import DataFlow::PathGraph
import MyBatisMapperXmlSqlInjectionLib import MyBatisMapperXmlSqlInjectionLib
import semmle.code.xml.MyBatisMapperXML import semmle.code.xml.MyBatisMapperXML
import semmle.code.java.security.SanitizerGuard
import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.FlowSources
private class MyBatisMapperXmlSqlInjectionConfiguration extends TaintTracking::Configuration { private class MyBatisMapperXmlSqlInjectionConfiguration extends TaintTracking::Configuration {
@@ -33,10 +32,6 @@ private class MyBatisMapperXmlSqlInjectionConfiguration extends TaintTracking::C
node.getType() instanceof NumberType node.getType() instanceof NumberType
} }
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
guard instanceof ContainsSanitizer or guard instanceof EqualsSanitizer
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma | exists(MethodAccess ma |
ma.getMethod().getDeclaringType() instanceof MapType and ma.getMethod().getDeclaringType() instanceof MapType and
@@ -61,5 +56,5 @@ where
cfg.hasFlowPath(source, sink) and cfg.hasFlowPath(source, sink) and
isMapperXmlSqlInjection(sink.getNode(), xmle) isMapperXmlSqlInjection(sink.getNode(), xmle)
select sink.getNode(), source, sink, select sink.getNode(), source, sink,
"MyBatis Mapper XML sql injection might include code from $@ to $@.", source.getNode(), "MyBatis Mapper XML SQL injection might include code from $@ to $@.", source.getNode(),
"this user input", xmle, "this sql operation" "this user input", xmle, "this SQL operation"

View File

@@ -1,3 +1,7 @@
/**
* Provide classes for SQL injection detection in MyBatis Mapper XML.
*/
import java import java
import MyBatisCommonLib import MyBatisCommonLib
import semmle.code.xml.MyBatisMapperXML import semmle.code.xml.MyBatisMapperXML
@@ -17,116 +21,120 @@ class MyBatisMapperMethodCallAnArgument extends DataFlow::Node {
/** Get the #{...} or ${...} parameters in the Mybatis mapper xml file */ /** Get the #{...} or ${...} parameters in the Mybatis mapper xml file */
private string getAnMybatiXmlSetValue(XMLElement xmle) { private string getAnMybatiXmlSetValue(XMLElement xmle) {
result = xmle.getTextValue().trim().regexpFind("(#|\\$)(\\{([^\\}]*\\}))", _, _) result = xmle.getTextValue().trim().regexpFind("(#|\\$)\\{[^\\}]*\\}", _, _)
} }
predicate isMapperXmlSqlInjection(DataFlow::Node node, XMLElement xmle) { predicate isMapperXmlSqlInjection(DataFlow::Node node, XMLElement xmle) {
// MyBatis Mapper method Param Annotation sql injection vulnerabilities. // MyBatis Mapper method Param Annotation sql injection vulnerabilities.
// e.g. MyBatis Mapper method: `void test(@Param("orderby") String name);` and MyBatis Mapper XML file:`select id,name from test order by ${orderby,jdbcType=VARCHAR}` // e.g. MyBatis Mapper method: `void test(@Param("orderby") String name);` and MyBatis Mapper XML file:`select id,name from test order by ${orderby,jdbcType=VARCHAR}`
exists( exists(MyBatisMapperSqlOperation mbmxe, MethodAccess ma, int i, Annotation annotation |
MyBatisMapperSqlOperation mbmxe, MyBatisMapperSql mbms, MethodAccess mc, int i, mbmxe.getMapperMethod() = ma.getMethod()
Annotation annotation
|
mbmxe.getMapperMethod() = mc.getMethod()
| |
( (
mbmxe.getAChild*() = xmle mbmxe.getAChild*() = xmle
or or
exists(MyBatisMapperSql mbms |
mbmxe.getInclude().getRefid() = mbms.getId() and mbmxe.getInclude().getRefid() = mbms.getId() and
mbms.getAChild*() = xmle mbms.getAChild*() = xmle
)
) and ) and
mc.getMethod().getParameter(i).hasAnnotation() and ma.getMethod().getParameter(i).getAnAnnotation() = annotation and
mc.getMethod().getParameter(i).getAnAnnotation() = annotation and
annotation.getType() instanceof TypeParam and annotation.getType() instanceof TypeParam and
getAnMybatiXmlSetValue(xmle) getAnMybatiXmlSetValue(xmle)
.matches("%${" + annotation.getValue("value").(CompileTimeConstantExpr).getStringValue() + .matches("%${" + annotation.getValue("value").(CompileTimeConstantExpr).getStringValue() +
"%}") and "%}") and
mc.getArgument(i) = node.asExpr() ma.getArgument(i) = node.asExpr()
) )
or or
// MyBatis Mapper method Class Field sql injection vulnerabilities. // MyBatis Mapper method Class Field sql injection vulnerabilities.
// e.g. MyBatis Mapper method: `void test(Test test);` and MyBatis Mapper XML file:`select id,name from test order by ${name,jdbcType=VARCHAR}` // e.g. MyBatis Mapper method: `void test(Test test);` and MyBatis Mapper XML file:`select id,name from test order by ${name,jdbcType=VARCHAR}`
exists(MyBatisMapperSqlOperation mbmxe, MyBatisMapperSql mbms, MethodAccess mc, int i, Class c | exists(MyBatisMapperSqlOperation mbmxe, MethodAccess ma, int i, RefType t |
mbmxe.getMapperMethod() = mc.getMethod() mbmxe.getMapperMethod() = ma.getMethod()
| |
( (
mbmxe.getAChild*() = xmle mbmxe.getAChild*() = xmle
or or
exists(MyBatisMapperSql mbms |
mbmxe.getInclude().getRefid() = mbms.getId() and mbmxe.getInclude().getRefid() = mbms.getId() and
mbms.getAChild*() = xmle mbms.getAChild*() = xmle
)
) and ) and
not mc.getMethod().getParameter(i).hasAnnotation() and not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
mc.getMethod().getParameterType(i).getName() = c.getName() and ma.getMethod().getParameterType(i).getName() = t.getName() and
getAnMybatiXmlSetValue(xmle).matches("%${" + c.getAField().getName() + "%}") and getAnMybatiXmlSetValue(xmle).matches("%${" + t.getAField().getName() + "%}") and
mc.getArgument(i) = node.asExpr() ma.getArgument(i) = node.asExpr()
) )
or or
// The parameter type of MyBatis Mapper method is Map or List or Array, which may cause SQL injection vulnerability. // The parameter type of MyBatis Mapper method is Map or List or Array, which may cause SQL injection vulnerability.
// e.g. MyBatis Mapper method: `void test(Map<String, String> params);` and MyBatis Mapper XML file:`select id,name from test where name like '%${name}%'` // e.g. MyBatis Mapper method: `void test(Map<String, String> params);` and MyBatis Mapper XML file:`select id,name from test where name like '%${name}%'`
exists( exists(
MyBatisMapperSqlOperation mbmxe, MyBatisMapperForeach mbmf, MyBatisMapperSql mbms, MyBatisMapperSqlOperation mbmxe, MyBatisMapperForeach mbmf, MethodAccess ma, int i, string res
MethodAccess mc, int i, string res
| |
mbmxe.getMapperMethod() = mc.getMethod() mbmxe.getMapperMethod() = ma.getMethod()
| |
mbmf = xmle and mbmf = xmle and
( (
mbmxe.getAChild*() = xmle mbmxe.getAChild*() = xmle
or or
exists(MyBatisMapperSql mbms |
mbmxe.getInclude().getRefid() = mbms.getId() and mbmxe.getInclude().getRefid() = mbms.getId() and
mbms.getAChild*() = xmle mbms.getAChild*() = xmle
)
) and ) and
not mc.getMethod().getParameter(i).hasAnnotation() and not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
( (
mc.getMethod().getParameterType(i) instanceof MapType or ma.getMethod().getParameterType(i) instanceof MapType or
mc.getMethod().getParameterType(i) instanceof ListType or ma.getMethod().getParameterType(i) instanceof ListType or
mc.getMethod().getParameterType(i) instanceof Array ma.getMethod().getParameterType(i) instanceof Array
) and ) and
res = getAnMybatiXmlSetValue(xmle) and res = getAnMybatiXmlSetValue(xmle) and
res.matches("%${%}") and res.matches("%${%}") and
not res.matches("${" + getAnMybatisConfigurationVariableKey() + "}") and not res = "${" + getAnMybatisConfigurationVariableKey() + "}" and
mc.getArgument(i) = node.asExpr() ma.getArgument(i) = node.asExpr()
) )
or or
// SQL injection vulnerability where the MyBatis Mapper method has only one parameter and the parameter is not annotated with `@Param`. // SQL injection vulnerability where the MyBatis Mapper method has only one parameter and the parameter is not annotated with `@Param`.
// e.g. MyBatis Mapper method: `void test(String name);` and MyBatis Mapper XML file:`select id,name from test where name like '%${value}%'` // e.g. MyBatis Mapper method: `void test(String name);` and MyBatis Mapper XML file:`select id,name from test where name like '%${value}%'`
exists(MyBatisMapperSqlOperation mbmxe, MyBatisMapperSql mbms, MethodAccess mc, string res | exists(MyBatisMapperSqlOperation mbmxe, MethodAccess ma, string res |
mbmxe.getMapperMethod() = mc.getMethod() mbmxe.getMapperMethod() = ma.getMethod()
| |
( (
mbmxe.getAChild*() = xmle mbmxe.getAChild*() = xmle
or or
exists(MyBatisMapperSql mbms |
mbmxe.getInclude().getRefid() = mbms.getId() and mbmxe.getInclude().getRefid() = mbms.getId() and
mbms.getAChild*() = xmle mbms.getAChild*() = xmle
)
) and ) and
res = getAnMybatiXmlSetValue(xmle) and res = getAnMybatiXmlSetValue(xmle) and
mc.getMethod().getNumberOfParameters() = 1 and ma.getMethod().getNumberOfParameters() = 1 and
not mc.getMethod().getAParameter().hasAnnotation() and not ma.getMethod().getAParameter().getAnAnnotation().getType() instanceof TypeParam and
res.matches("%${%}") and res.matches("%${%}") and
not res.matches("${" + getAnMybatisConfigurationVariableKey() + "}") and not res = "${" + getAnMybatisConfigurationVariableKey() + "}" and
mc.getAnArgument() = node.asExpr() ma.getAnArgument() = node.asExpr()
) )
or or
// MyBatis Mapper method default parameter sql injection vulnerabilities.the default parameter form of the method is arg[0...n] or param[1...n]. // MyBatis Mapper method default parameter sql injection vulnerabilities.the default parameter form of the method is arg[0...n] or param[1...n].
// e.g. MyBatis Mapper method: `void test(String name);` and MyBatis Mapper XML file:`select id,name from test where name like '%${arg0 or param1}%'` // e.g. MyBatis Mapper method: `void test(String name);` and MyBatis Mapper XML file:`select id,name from test where name like '%${arg0 or param1}%'`
exists( exists(MyBatisMapperSqlOperation mbmxe, MethodAccess ma, int i, string res |
MyBatisMapperSqlOperation mbmxe, MyBatisMapperSql mbms, MethodAccess mc, int i, string res mbmxe.getMapperMethod() = ma.getMethod()
|
mbmxe.getMapperMethod() = mc.getMethod()
| |
( (
mbmxe.getAChild*() = xmle mbmxe.getAChild*() = xmle
or or
exists(MyBatisMapperSql mbms |
mbmxe.getInclude().getRefid() = mbms.getId() and mbmxe.getInclude().getRefid() = mbms.getId() and
mbms.getAChild*() = xmle mbms.getAChild*() = xmle
)
) and ) and
not mc.getMethod().getParameter(i).hasAnnotation() and not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
res = getAnMybatiXmlSetValue(xmle) and res = getAnMybatiXmlSetValue(xmle) and
( (
res.matches("%${param" + (i + 1) + "%}") res.matches("%${param" + (i + 1) + "%}")
or or
res.matches("%${arg" + i + "%}") res.matches("%${arg" + i + "%}")
) and ) and
mc.getArgument(i) = node.asExpr() not res = "${" + getAnMybatisConfigurationVariableKey() + "}" and
ma.getArgument(i) = node.asExpr()
) )
} }

View File

@@ -1,33 +0,0 @@
/**
* Provide universal sanitizer guards.
*/
import java
import semmle.code.java.dataflow.DataFlow
/**
* An contains method sanitizer guard.
*
* e.g. `if(test.contains("test")) {...`
*/
class ContainsSanitizer extends DataFlow::BarrierGuard {
ContainsSanitizer() { this.(MethodAccess).getMethod().hasName("contains") }
override predicate checks(Expr e, boolean branch) {
e = this.(MethodAccess).getArgument(0) and branch = true
}
}
/**
* An equals method sanitizer guard.
*
* e.g. `if("test".equals(test)) {...`
*/
class EqualsSanitizer extends DataFlow::BarrierGuard {
EqualsSanitizer() { this.(MethodAccess).getMethod().hasName("equals") }
override predicate checks(Expr e, boolean branch) {
e = [this.(MethodAccess).getArgument(0), this.(MethodAccess).getQualifier()] and
branch = true
}
}

View File

@@ -1,3 +1,7 @@
/**
* Provides classes for working with MyBatis mapper xml files and their content.
*/
import java import java
/** /**
@@ -20,12 +24,14 @@ class MyBatisMapperXMLElement extends XMLElement {
/** /**
* Gets the value for this element, with leading and trailing whitespace trimmed. * Gets the value for this element, with leading and trailing whitespace trimmed.
*/ */
string getValue() { result = allCharactersString().trim() } string getValue() { result = this.allCharactersString().trim() }
/** /**
* Gets the reference type bound to MyBatis Mapper XML File. * Gets the reference type bound to MyBatis Mapper XML File.
*/ */
RefType getNamespaceRefType() { result.getQualifiedName() = getAttribute("namespace").getValue() } RefType getNamespaceRefType() {
result.getQualifiedName() = this.getAttribute("namespace").getValue()
}
} }
/** /**
@@ -37,8 +43,11 @@ abstract class MyBatisMapperSqlOperation extends MyBatisMapperXMLElement {
/** /**
* Gets the `<include>` element in a `MyBatisMapperSqlOperation`. * Gets the `<include>` element in a `MyBatisMapperSqlOperation`.
*/ */
MyBatisMapperInclude getInclude() { result = getAChild*() } MyBatisMapperInclude getInclude() { result = this.getAChild*() }
/**
* Gets the method bound to MyBatis Mapper XML File.
*/
Method getMapperMethod() { Method getMapperMethod() {
result.getName() = this.getId() and result.getName() = this.getId() and
result.getDeclaringType() = this.getParent().(MyBatisMapperXMLElement).getNamespaceRefType() result.getDeclaringType() = this.getParent().(MyBatisMapperXMLElement).getNamespaceRefType()
@@ -49,72 +58,72 @@ abstract class MyBatisMapperSqlOperation extends MyBatisMapperXMLElement {
* A `<insert>` element in a `MyBatisMapperSqlOperation`. * A `<insert>` element in a `MyBatisMapperSqlOperation`.
*/ */
class MyBatisMapperInsert extends MyBatisMapperSqlOperation { class MyBatisMapperInsert extends MyBatisMapperSqlOperation {
MyBatisMapperInsert() { getName() = "insert" } MyBatisMapperInsert() { this.getName() = "insert" }
/** /**
* Gets the value of the `id` attribute of this `<insert>`. * Gets the value of the `id` attribute of this `<insert>`.
*/ */
override string getId() { result = getAttribute("id").getValue() } override string getId() { result = this.getAttribute("id").getValue() }
} }
/** /**
* A `<update>` element in a `MyBatisMapperSqlOperation`. * A `<update>` element in a `MyBatisMapperSqlOperation`.
*/ */
class MyBatisMapperUpdate extends MyBatisMapperSqlOperation { class MyBatisMapperUpdate extends MyBatisMapperSqlOperation {
MyBatisMapperUpdate() { getName() = "update" } MyBatisMapperUpdate() { this.getName() = "update" }
/** /**
* Gets the value of the `id` attribute of this `<update>`. * Gets the value of the `id` attribute of this `<update>`.
*/ */
override string getId() { result = getAttribute("id").getValue() } override string getId() { result = this.getAttribute("id").getValue() }
} }
/** /**
* A `<delete>` element in a `MyBatisMapperSqlOperation`. * A `<delete>` element in a `MyBatisMapperSqlOperation`.
*/ */
class MyBatisMapperDelete extends MyBatisMapperSqlOperation { class MyBatisMapperDelete extends MyBatisMapperSqlOperation {
MyBatisMapperDelete() { getName() = "delete" } MyBatisMapperDelete() { this.getName() = "delete" }
/** /**
* Gets the value of the `id` attribute of this `<delete>`. * Gets the value of the `id` attribute of this `<delete>`.
*/ */
override string getId() { result = getAttribute("id").getValue() } override string getId() { result = this.getAttribute("id").getValue() }
} }
/** /**
* A `<select>` element in a `MyBatisMapperSqlOperation`. * A `<select>` element in a `MyBatisMapperSqlOperation`.
*/ */
class MyBatisMapperSelect extends MyBatisMapperSqlOperation { class MyBatisMapperSelect extends MyBatisMapperSqlOperation {
MyBatisMapperSelect() { getName() = "select" } MyBatisMapperSelect() { this.getName() = "select" }
/** /**
* Gets the value of the `id` attribute of this `<select>`. * Gets the value of the `id` attribute of this `<select>`.
*/ */
override string getId() { result = getAttribute("id").getValue() } override string getId() { result = this.getAttribute("id").getValue() }
} }
/** /**
* A `<select>` element in a `MyBatisMapperXMLElement`. * A `<select>` element in a `MyBatisMapperXMLElement`.
*/ */
class MyBatisMapperSql extends MyBatisMapperXMLElement { class MyBatisMapperSql extends MyBatisMapperXMLElement {
MyBatisMapperSql() { getName() = "sql" } MyBatisMapperSql() { this.getName() = "sql" }
/** /**
* Gets the value of the `id` attribute of this `<sql>`. * Gets the value of the `id` attribute of this `<sql>`.
*/ */
string getId() { result = getAttribute("id").getValue() } string getId() { result = this.getAttribute("id").getValue() }
} }
/** /**
* A `<include>` element in a `MyBatisMapperXMLElement`. * A `<include>` element in a `MyBatisMapperXMLElement`.
*/ */
class MyBatisMapperInclude extends MyBatisMapperXMLElement { class MyBatisMapperInclude extends MyBatisMapperXMLElement {
MyBatisMapperInclude() { getName() = "include" } MyBatisMapperInclude() { this.getName() = "include" }
/** /**
* Gets the value of the `refid` attribute of this `<include>`. * Gets the value of the `refid` attribute of this `<include>`.
*/ */
string getRefid() { result = getAttribute("refid").getValue() } string getRefid() { result = this.getAttribute("refid").getValue() }
} }
/** /**

View File

@@ -13,4 +13,4 @@ nodes
| MybatisSqlInjectionService.java:51:27:51:33 | hashMap | semmle.label | hashMap | | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | semmle.label | hashMap |
subpaths subpaths
#select #select
| MybatisSqlInjectionService.java:51:27:51:33 | hashMap | MybatisSqlInjection.java:62:19:62:43 | name : String | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | MyBatis annotation sql injection might include code from $@ to $@. | MybatisSqlInjection.java:62:19:62:43 | name | this user input | SqlInjectionMapper.java:29:2:29:54 | Select | this sql operation | | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | MybatisSqlInjection.java:62:19:62:43 | name : String | MybatisSqlInjectionService.java:51:27:51:33 | hashMap | MyBatis annotation SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:62:19:62:43 | name | this user input | SqlInjectionMapper.java:29:2:29:54 | Select | this SQL operation |

View File

@@ -15,8 +15,6 @@ edges
| MybatisSqlInjection.java:53:35:53:40 | params : List | MybatisSqlInjectionService.java:40:19:40:37 | params : List | | MybatisSqlInjection.java:53:35:53:40 | params : List | MybatisSqlInjectionService.java:40:19:40:37 | params : List |
| MybatisSqlInjection.java:57:19:57:46 | params : String[] | MybatisSqlInjection.java:58:35:58:40 | params : String[] | | MybatisSqlInjection.java:57:19:57:46 | params : String[] | MybatisSqlInjection.java:58:35:58:40 | params : String[] |
| MybatisSqlInjection.java:58:35:58:40 | params : String[] | MybatisSqlInjectionService.java:44:19:44:33 | params : String[] | | MybatisSqlInjection.java:58:35:58:40 | params : String[] | MybatisSqlInjectionService.java:44:19:44:33 | params : String[] |
| MybatisSqlInjection.java:73:26:73:36 | name : String | MybatisSqlInjection.java:74:56:74:59 | name : String |
| MybatisSqlInjection.java:74:56:74:59 | name : String | MybatisSqlInjectionService.java:59:26:59:36 | name : String |
| MybatisSqlInjectionService.java:13:25:13:35 | name : String | MybatisSqlInjectionService.java:14:47:14:50 | name | | MybatisSqlInjectionService.java:13:25:13:35 | name : String | MybatisSqlInjectionService.java:14:47:14:50 | name |
| MybatisSqlInjectionService.java:18:25:18:35 | name : String | MybatisSqlInjectionService.java:19:47:19:50 | name | | MybatisSqlInjectionService.java:18:25:18:35 | name : String | MybatisSqlInjectionService.java:19:47:19:50 | name |
| MybatisSqlInjectionService.java:23:25:23:33 | test : Test | MybatisSqlInjectionService.java:24:47:24:50 | test | | MybatisSqlInjectionService.java:23:25:23:33 | test : Test | MybatisSqlInjectionService.java:24:47:24:50 | test |
@@ -25,7 +23,6 @@ edges
| MybatisSqlInjectionService.java:36:19:36:44 | params : Map | MybatisSqlInjectionService.java:37:27:37:32 | params | | MybatisSqlInjectionService.java:36:19:36:44 | params : Map | MybatisSqlInjectionService.java:37:27:37:32 | params |
| MybatisSqlInjectionService.java:40:19:40:37 | params : List | MybatisSqlInjectionService.java:41:27:41:32 | params | | MybatisSqlInjectionService.java:40:19:40:37 | params : List | MybatisSqlInjectionService.java:41:27:41:32 | params |
| MybatisSqlInjectionService.java:44:19:44:33 | params : String[] | MybatisSqlInjectionService.java:45:27:45:32 | params | | MybatisSqlInjectionService.java:44:19:44:33 | params : String[] | MybatisSqlInjectionService.java:45:27:45:32 | params |
| MybatisSqlInjectionService.java:59:26:59:36 | name : String | MybatisSqlInjectionService.java:60:48:60:51 | name |
nodes nodes
| MybatisSqlInjection.java:19:25:19:49 | name : String | semmle.label | name : String | | MybatisSqlInjection.java:19:25:19:49 | name : String | semmle.label | name : String |
| MybatisSqlInjection.java:20:55:20:58 | name : String | semmle.label | name : String | | MybatisSqlInjection.java:20:55:20:58 | name : String | semmle.label | name : String |
@@ -43,8 +40,6 @@ nodes
| MybatisSqlInjection.java:53:35:53:40 | params : List | semmle.label | params : List | | MybatisSqlInjection.java:53:35:53:40 | params : List | semmle.label | params : List |
| MybatisSqlInjection.java:57:19:57:46 | params : String[] | semmle.label | params : String[] | | MybatisSqlInjection.java:57:19:57:46 | params : String[] | semmle.label | params : String[] |
| MybatisSqlInjection.java:58:35:58:40 | params : String[] | semmle.label | params : String[] | | MybatisSqlInjection.java:58:35:58:40 | params : String[] | semmle.label | params : String[] |
| MybatisSqlInjection.java:73:26:73:36 | name : String | semmle.label | name : String |
| MybatisSqlInjection.java:74:56:74:59 | name : String | semmle.label | name : String |
| MybatisSqlInjectionService.java:13:25:13:35 | name : String | semmle.label | name : String | | MybatisSqlInjectionService.java:13:25:13:35 | name : String | semmle.label | name : String |
| MybatisSqlInjectionService.java:14:47:14:50 | name | semmle.label | name | | MybatisSqlInjectionService.java:14:47:14:50 | name | semmle.label | name |
| MybatisSqlInjectionService.java:18:25:18:35 | name : String | semmle.label | name : String | | MybatisSqlInjectionService.java:18:25:18:35 | name : String | semmle.label | name : String |
@@ -61,16 +56,14 @@ nodes
| MybatisSqlInjectionService.java:41:27:41:32 | params | semmle.label | params | | MybatisSqlInjectionService.java:41:27:41:32 | params | semmle.label | params |
| MybatisSqlInjectionService.java:44:19:44:33 | params : String[] | semmle.label | params : String[] | | MybatisSqlInjectionService.java:44:19:44:33 | params : String[] | semmle.label | params : String[] |
| MybatisSqlInjectionService.java:45:27:45:32 | params | semmle.label | params | | MybatisSqlInjectionService.java:45:27:45:32 | params | semmle.label | params |
| MybatisSqlInjectionService.java:59:26:59:36 | name : String | semmle.label | name : String |
| MybatisSqlInjectionService.java:60:48:60:51 | name | semmle.label | name |
subpaths subpaths
#select #select
| MybatisSqlInjectionService.java:14:47:14:50 | name | MybatisSqlInjection.java:19:25:19:49 | name : String | MybatisSqlInjectionService.java:14:47:14:50 | name | MyBatis Mapper XML sql injection might include code from $@ to $@. | MybatisSqlInjection.java:19:25:19:49 | name | this user input | SqlInjectionMapper.xml:23:3:25:12 | select | this sql operation | | MybatisSqlInjectionService.java:14:47:14:50 | name | MybatisSqlInjection.java:19:25:19:49 | name : String | MybatisSqlInjectionService.java:14:47:14:50 | name | MyBatis Mapper XML SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:19:25:19:49 | name | this user input | SqlInjectionMapper.xml:23:3:25:12 | select | this SQL operation |
| MybatisSqlInjectionService.java:19:47:19:50 | name | MybatisSqlInjection.java:25:25:25:49 | name : String | MybatisSqlInjectionService.java:19:47:19:50 | name | MyBatis Mapper XML sql injection might include code from $@ to $@. | MybatisSqlInjection.java:25:25:25:49 | name | this user input | SqlInjectionMapper.xml:27:3:29:12 | select | this sql operation | | MybatisSqlInjectionService.java:19:47:19:50 | name | MybatisSqlInjection.java:25:25:25:49 | name : String | MybatisSqlInjectionService.java:19:47:19:50 | name | MyBatis Mapper XML SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:25:25:25:49 | name | this user input | SqlInjectionMapper.xml:27:3:29:12 | select | this SQL operation |
| MybatisSqlInjectionService.java:24:47:24:50 | test | MybatisSqlInjection.java:31:25:31:49 | test : Test | MybatisSqlInjectionService.java:24:47:24:50 | test | MyBatis Mapper XML sql injection might include code from $@ to $@. | MybatisSqlInjection.java:31:25:31:49 | test | this user input | SqlInjectionMapper.xml:31:3:33:12 | select | this sql operation | | MybatisSqlInjectionService.java:24:47:24:50 | test | MybatisSqlInjection.java:31:25:31:49 | test : Test | MybatisSqlInjectionService.java:24:47:24:50 | test | MyBatis Mapper XML SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:31:25:31:49 | test | this user input | SqlInjectionMapper.xml:31:3:33:12 | select | this SQL operation |
| MybatisSqlInjectionService.java:29:27:29:30 | test | MybatisSqlInjection.java:37:19:37:40 | test : Test | MybatisSqlInjectionService.java:29:27:29:30 | test | MyBatis Mapper XML sql injection might include code from $@ to $@. | MybatisSqlInjection.java:37:19:37:40 | test | this user input | SqlInjectionMapper.xml:14:7:16:12 | if | this sql operation | | MybatisSqlInjectionService.java:29:27:29:30 | test | MybatisSqlInjection.java:37:19:37:40 | test : Test | MybatisSqlInjectionService.java:29:27:29:30 | test | MyBatis Mapper XML SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:37:19:37:40 | test | this user input | SqlInjectionMapper.xml:14:7:16:12 | if | this SQL operation |
| MybatisSqlInjectionService.java:33:27:33:30 | test | MybatisSqlInjection.java:42:19:42:40 | test : Test | MybatisSqlInjectionService.java:33:27:33:30 | test | MyBatis Mapper XML sql injection might include code from $@ to $@. | MybatisSqlInjection.java:42:19:42:40 | test | this user input | SqlInjectionMapper.xml:50:7:52:12 | if | this sql operation | | MybatisSqlInjectionService.java:33:27:33:30 | test | MybatisSqlInjection.java:42:19:42:40 | test : Test | MybatisSqlInjectionService.java:33:27:33:30 | test | MyBatis Mapper XML SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:42:19:42:40 | test | this user input | SqlInjectionMapper.xml:50:7:52:12 | if | this SQL operation |
| MybatisSqlInjectionService.java:33:27:33:30 | test | MybatisSqlInjection.java:42:19:42:40 | test : Test | MybatisSqlInjectionService.java:33:27:33:30 | test | MyBatis Mapper XML sql injection might include code from $@ to $@. | MybatisSqlInjection.java:42:19:42:40 | test | this user input | SqlInjectionMapper.xml:53:7:55:12 | if | this sql operation | | MybatisSqlInjectionService.java:33:27:33:30 | test | MybatisSqlInjection.java:42:19:42:40 | test : Test | MybatisSqlInjectionService.java:33:27:33:30 | test | MyBatis Mapper XML SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:42:19:42:40 | test | this user input | SqlInjectionMapper.xml:53:7:55:12 | if | this SQL operation |
| MybatisSqlInjectionService.java:37:27:37:32 | params | MybatisSqlInjection.java:47:19:47:57 | params : Map | MybatisSqlInjectionService.java:37:27:37:32 | params | MyBatis Mapper XML sql injection might include code from $@ to $@. | MybatisSqlInjection.java:47:19:47:57 | params | this user input | SqlInjectionMapper.xml:59:3:61:12 | select | this sql operation | | MybatisSqlInjectionService.java:37:27:37:32 | params | MybatisSqlInjection.java:47:19:47:57 | params : Map | MybatisSqlInjectionService.java:37:27:37:32 | params | MyBatis Mapper XML SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:47:19:47:57 | params | this user input | SqlInjectionMapper.xml:59:3:61:12 | select | this SQL operation |
| MybatisSqlInjectionService.java:41:27:41:32 | params | MybatisSqlInjection.java:52:19:52:50 | params : List | MybatisSqlInjectionService.java:41:27:41:32 | params | MyBatis Mapper XML sql injection might include code from $@ to $@. | MybatisSqlInjection.java:52:19:52:50 | params | this user input | SqlInjectionMapper.xml:65:5:67:15 | foreach | this sql operation | | MybatisSqlInjectionService.java:41:27:41:32 | params | MybatisSqlInjection.java:52:19:52:50 | params : List | MybatisSqlInjectionService.java:41:27:41:32 | params | MyBatis Mapper XML SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:52:19:52:50 | params | this user input | SqlInjectionMapper.xml:65:5:67:15 | foreach | this SQL operation |
| MybatisSqlInjectionService.java:45:27:45:32 | params | MybatisSqlInjection.java:57:19:57:46 | params : String[] | MybatisSqlInjectionService.java:45:27:45:32 | params | MyBatis Mapper XML sql injection might include code from $@ to $@. | MybatisSqlInjection.java:57:19:57:46 | params | this user input | SqlInjectionMapper.xml:72:5:74:15 | foreach | this sql operation | | MybatisSqlInjectionService.java:45:27:45:32 | params | MybatisSqlInjection.java:57:19:57:46 | params : String[] | MybatisSqlInjectionService.java:45:27:45:32 | params | MyBatis Mapper XML SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:57:19:57:46 | params | this user input | SqlInjectionMapper.xml:72:5:74:15 | foreach | this SQL operation |

View File

@@ -68,10 +68,4 @@ public class MybatisSqlInjection {
List<Test> result = mybatisSqlInjectionService.good1(id); List<Test> result = mybatisSqlInjectionService.good1(id);
return result; return result;
} }
@GetMapping(value = "good2")
public List<Test> good2(String name) {
List<Test> result = mybatisSqlInjectionService.good2(name);
return result;
}
} }

View File

@@ -55,9 +55,4 @@ public class MybatisSqlInjectionService {
List<Test> result = sqlInjectionMapper.good1(id); List<Test> result = sqlInjectionMapper.good1(id);
return result; return result;
} }
public List<Test> good2(String name) {
List<Test> result = sqlInjectionMapper.good2(name);
return result;
}
} }

View File

@@ -30,6 +30,4 @@ public interface SqlInjectionMapper {
public Test bad9(HashMap<String, Object> map); public Test bad9(HashMap<String, Object> map);
List<Test> good1(Integer id); List<Test> good1(Integer id);
List<Test> good2(String name);
} }

View File

@@ -77,8 +77,4 @@
<select id="good1" parameterType="java.lang.Integer" resultMap="BaseResultMap"> <select id="good1" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select id,name from test where id = ${id} select id,name from test where id = ${id}
</select> </select>
<select id="good2" parameterType="java.lang.String" resultMap="BaseResultMap">
select id,name from test where name = #{name}
</select>
</mapper> </mapper>