mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
New model: SQL injection in MyBatis annotations
This commit is contained in:
@@ -40,3 +40,119 @@ class IbatisConfigurationGetVariablesMethod extends Method {
|
||||
getNumberOfParameters() = 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An annotation type that identifies Ibatis select.
|
||||
*/
|
||||
private class IbatisSelectAnnotationType extends AnnotationType {
|
||||
IbatisSelectAnnotationType() {
|
||||
this.hasQualifiedName("org.apache.ibatis.annotations", "Select") or
|
||||
this.getAnAnnotation().getType() instanceof IbatisSelectAnnotationType
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An annotation type that identifies Ibatis delete.
|
||||
*/
|
||||
private class IbatisDeleteAnnotationType extends AnnotationType {
|
||||
IbatisDeleteAnnotationType() {
|
||||
this.hasQualifiedName("org.apache.ibatis.annotations", "Delete") or
|
||||
this.getAnAnnotation().getType() instanceof IbatisDeleteAnnotationType
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An annotation type that identifies Ibatis insert.
|
||||
*/
|
||||
private class IbatisInsertAnnotationType extends AnnotationType {
|
||||
IbatisInsertAnnotationType() {
|
||||
this.hasQualifiedName("org.apache.ibatis.annotations", "Insert") or
|
||||
this.getAnAnnotation().getType() instanceof IbatisInsertAnnotationType
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An annotation type that identifies Ibatis update.
|
||||
*/
|
||||
private class IbatisUpdateAnnotationType extends AnnotationType {
|
||||
IbatisUpdateAnnotationType() {
|
||||
this.hasQualifiedName("org.apache.ibatis.annotations", "Update") or
|
||||
this.getAnAnnotation().getType() instanceof IbatisUpdateAnnotationType
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ibatis sql operation annotation.
|
||||
*/
|
||||
abstract class IbatisSqlOperationAnnotation extends Annotation {
|
||||
abstract string getSqlValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* A `@org.apache.ibatis.annotations.Select` annotation.
|
||||
*/
|
||||
private class IbatisSelectAnnotation extends IbatisSqlOperationAnnotation {
|
||||
IbatisSelectAnnotation() { this.getType() instanceof IbatisSelectAnnotationType }
|
||||
|
||||
string getSelectValue() {
|
||||
result = this.getValue("value").(CompileTimeConstantExpr).getStringValue() or
|
||||
result =
|
||||
this.getValue("value").(ArrayInit).getInit(_).(CompileTimeConstantExpr).getStringValue()
|
||||
}
|
||||
|
||||
override string getSqlValue() { result = getSelectValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `@org.apache.ibatis.annotations.Delete` annotation.
|
||||
*/
|
||||
private class IbatisDeleteAnnotation extends IbatisSqlOperationAnnotation {
|
||||
IbatisDeleteAnnotation() { this.getType() instanceof IbatisDeleteAnnotationType }
|
||||
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
public interface MyBatisAnnotationSqlInjection {
|
||||
|
||||
@Select("select * from test where name = ${name}")
|
||||
public Test bad1(String name);
|
||||
|
||||
@Select("select * from test where name = #{name}")
|
||||
public Test good1(String name);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>MyBatis operates the database by using @Select, @Insert, etc. annotations in the method, and can use the $ character
|
||||
to construct dynamic SQL statements. Attackers can modify the meaning of statements or execute arbitrary SQL commands.</p>
|
||||
</overview>
|
||||
|
||||
<<recommendation>
|
||||
<p>
|
||||
When writing MyBatis mapping statements, try to use the format "#{xxx}". If you have to use parameters
|
||||
such as "${xxx}", you must manually filter to prevent SQL injection attacks.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
The following examples show the bad situation and the good situation respectively. 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.
|
||||
The good1 method uses the <code>#{name}</code> method in the <code>@Select</code> annotation to splice SQL statements,
|
||||
and the MyBatis framework will handle the dangerous characters entered by the user, And did not cause SQL injection vulnerabilities.
|
||||
</p>
|
||||
<sample src="MyBatisAnnotationSqlInjection.java" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
Fortify:
|
||||
<a href="https://vulncat.fortify.com/en/detail?id=desc.config.java.sql_injection_mybatis_mapper">SQL Injection: MyBatis Mapper</a>.
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @name MyBatis annotation sql injection
|
||||
* @description Constructing a dynamic SQL statement with input that comes from an
|
||||
* untrusted source could allow an attacker to modify the statement's
|
||||
* meaning or to execute arbitrary SQL commands.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/sql-injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-089
|
||||
*/
|
||||
|
||||
import java
|
||||
import DataFlow::PathGraph
|
||||
import MyBatisAnnotationSqlInjectionLib
|
||||
import semmle.code.java.security.SanitizerGuard
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
|
||||
private class MyBatisAnnotationSqlInjectionConfiguration extends TaintTracking::Configuration {
|
||||
MyBatisAnnotationSqlInjectionConfiguration() { this = "MyBatis annotation sql injection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
sink instanceof MyBatisAnnotationMethodCallAnArgument
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
node.getType() instanceof PrimitiveType or
|
||||
node.getType() instanceof BoxedType or
|
||||
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) {
|
||||
exists(MethodAccess ma |
|
||||
ma.getMethod().getDeclaringType() instanceof MapType and
|
||||
ma.getMethod().getName() = "get" and
|
||||
ma.getQualifier() = node1.asExpr() and
|
||||
ma = node2.asExpr()
|
||||
)
|
||||
or
|
||||
exists(MethodAccess ma |
|
||||
ma.getMethod().getDeclaringType() instanceof TypeObject and
|
||||
ma.getMethod().getName() = "toString" and
|
||||
ma.getQualifier() = node1.asExpr() and
|
||||
ma = node2.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from
|
||||
MyBatisAnnotationSqlInjectionConfiguration cfg, DataFlow::PathNode source,
|
||||
DataFlow::PathNode sink, IbatisSqlOperationAnnotation isoa
|
||||
where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
isMybatisAnnotationSqlInjection(sink.getNode(), isoa)
|
||||
select sink.getNode(), source, sink,
|
||||
"MyBatis annotation sql injection might include code from $@ to $@.", source.getNode(),
|
||||
"this user input", isoa, "this sql operation"
|
||||
@@ -0,0 +1,126 @@
|
||||
import java
|
||||
import MyBatisCommonLib
|
||||
import semmle.code.xml.MyBatisMapperXML
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.frameworks.Properties
|
||||
|
||||
/** A sink for MyBatis annotation method call an argument. */
|
||||
class MyBatisAnnotationMethodCallAnArgument extends DataFlow::Node {
|
||||
MyBatisAnnotationMethodCallAnArgument() {
|
||||
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma | ma.getMethod() = msoam |
|
||||
ma.getAnArgument() = this.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the #{...} or ${...} parameters in the Mybatis annotation value. */
|
||||
private string getAnMybatiAnnotationSetValue(IbatisSqlOperationAnnotation isoa) {
|
||||
result = isoa.getSqlValue().trim().regexpFind("(#|\\$)(\\{([^\\}]*\\}))", _, _)
|
||||
}
|
||||
|
||||
predicate isMybatisAnnotationSqlInjection(DataFlow::Node node, IbatisSqlOperationAnnotation isoa) {
|
||||
// MyBatis uses an annotation method to perform SQL operations. This method has only one parameter and
|
||||
// the parameter is not annotated with `@Param`. Improper use of this parameter has a SQL injection vulnerability.
|
||||
// e.g.
|
||||
//
|
||||
// ```java
|
||||
// @Select(select id,name from test where name like '%${value}%')
|
||||
// Test test(String name);
|
||||
// ```
|
||||
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma, string res |
|
||||
msoam = ma.getMethod()
|
||||
|
|
||||
msoam.getAnAnnotation() = isoa and
|
||||
res = getAnMybatiAnnotationSetValue(isoa) and
|
||||
msoam.getNumberOfParameters() = 1 and
|
||||
not ma.getMethod().getAParameter().hasAnnotation() and
|
||||
res.matches("%${%}") and
|
||||
not res.matches("${" + getAnMybatisConfigurationVariableKey() + "}") and
|
||||
ma.getAnArgument() = node.asExpr()
|
||||
)
|
||||
or
|
||||
// MyBatis uses an annotation method to perform SQL operations. The parameter type of the method parameter
|
||||
// is Map or List or Array. SQL injection vulnerability caused by improper use of this parameter.
|
||||
// e.g.
|
||||
//
|
||||
// ```java
|
||||
// @Select(select id,name from test where name like '%${value}%')
|
||||
// Test test(Map map);
|
||||
// ```
|
||||
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, string res |
|
||||
msoam = ma.getMethod()
|
||||
|
|
||||
msoam.getAnAnnotation() = isoa and
|
||||
not ma.getMethod().getParameter(i).hasAnnotation() and
|
||||
(
|
||||
ma.getMethod().getParameterType(i) instanceof MapType or
|
||||
ma.getMethod().getParameterType(i) instanceof ListType or
|
||||
ma.getMethod().getParameterType(i) instanceof Array
|
||||
) and
|
||||
res = getAnMybatiAnnotationSetValue(isoa) and
|
||||
res.matches("%${%}") and
|
||||
not res.matches("${" + getAnMybatisConfigurationVariableKey() + "}") and
|
||||
ma.getArgument(i) = node.asExpr()
|
||||
)
|
||||
or
|
||||
// MyBatis uses annotation methods to perform SQL operations, and SQL injection vulnerabilities caused by
|
||||
// improper use of instance class fields.
|
||||
// e.g.
|
||||
//
|
||||
// ```java
|
||||
// @Select(select id,name from test order by ${name,jdbcType=VARCHAR})
|
||||
// void test(Test test);
|
||||
// ```
|
||||
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, Class c |
|
||||
msoam = ma.getMethod()
|
||||
|
|
||||
msoam.getAnAnnotation() = isoa and
|
||||
not ma.getMethod().getParameter(i).hasAnnotation() and
|
||||
ma.getMethod().getParameterType(i).getName() = c.getName() and
|
||||
getAnMybatiAnnotationSetValue(isoa).matches("%${" + c.getAField().getName() + "%}") and
|
||||
ma.getArgument(i) = node.asExpr()
|
||||
)
|
||||
or
|
||||
// MyBatis uses annotations to perform SQL operations. The method parameters use `@Param` annotation.
|
||||
// Due to improper use of this parameter, SQL injection vulnerabilities are caused.
|
||||
// e.g.
|
||||
//
|
||||
// ```java
|
||||
// @Select(select id,name from test order by ${orderby,jdbcType=VARCHAR})
|
||||
// void test(@Param("orderby") String name);
|
||||
// ```
|
||||
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, Annotation annotation |
|
||||
msoam = ma.getMethod()
|
||||
|
|
||||
msoam.getAnAnnotation() = isoa and
|
||||
ma.getMethod().getParameter(i).hasAnnotation() and
|
||||
ma.getMethod().getParameter(i).getAnAnnotation() = annotation and
|
||||
annotation.getType() instanceof TypeParam and
|
||||
getAnMybatiAnnotationSetValue(isoa)
|
||||
.matches("%${" + annotation.getValue("value").(CompileTimeConstantExpr).getStringValue() +
|
||||
"%}") and
|
||||
ma.getArgument(i) = node.asExpr()
|
||||
)
|
||||
or
|
||||
// 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.
|
||||
//
|
||||
// ```java
|
||||
// @Select(select id,name from test order by ${arg0,jdbcType=VARCHAR})
|
||||
// void test(String name);
|
||||
// ```
|
||||
exists(MybatisSqlOperationAnnotationMethod msoam, MethodAccess ma, int i, string res |
|
||||
msoam = ma.getMethod()
|
||||
|
|
||||
msoam.getAnAnnotation() = isoa and
|
||||
not ma.getMethod().getParameter(i).hasAnnotation() and
|
||||
res = getAnMybatiAnnotationSetValue(isoa) and
|
||||
(
|
||||
res.matches("%${param" + (i + 1) + "%}")
|
||||
or
|
||||
res.matches("%${arg" + i + "%}")
|
||||
) and
|
||||
not res.matches("${" + getAnMybatisConfigurationVariableKey() + "}") and
|
||||
ma.getArgument(i) = node.asExpr()
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.frameworks.MyBatis
|
||||
import semmle.code.java.frameworks.Properties
|
||||
|
||||
private predicate propertiesKey(DataFlow::Node prop, string key) {
|
||||
exists(MethodAccess m |
|
||||
m.getMethod() instanceof PropertiesSetPropertyMethod and
|
||||
key = m.getArgument(0).(CompileTimeConstantExpr).getStringValue() and
|
||||
prop.asExpr() = m.getQualifier()
|
||||
)
|
||||
}
|
||||
|
||||
/** A data flow configuration tracing flow from ibatis obtaining the variable configuration object to setting the value of the variable. */
|
||||
private class PropertiesFlowConfig extends DataFlow2::Configuration {
|
||||
PropertiesFlowConfig() { this = "PropertiesFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node src) {
|
||||
exists(MethodAccess ma | ma.getMethod() instanceof IbatisConfigurationGetVariablesMethod |
|
||||
src.asExpr() = ma
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { propertiesKey(sink, _) }
|
||||
}
|
||||
|
||||
/** Get the key value of Mybatis Configuration Variable. */
|
||||
string getAnMybatisConfigurationVariableKey() {
|
||||
exists(PropertiesFlowConfig conf, DataFlow::Node n |
|
||||
propertiesKey(n, result) and
|
||||
conf.hasFlow(_, 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`. */
|
||||
class ListType extends RefType {
|
||||
ListType() {
|
||||
this.getSourceDeclaration().getASourceSupertype*().hasQualifiedName("java.util", "List")
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
import java
|
||||
import DataFlow::PathGraph
|
||||
import MyBatisMapperXmlSqlInjectionLib
|
||||
import semmle.code.xml.MyBatisMapperXML
|
||||
import semmle.code.java.security.SanitizerGuard
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
|
||||
@@ -35,6 +36,22 @@ private class MyBatisMapperXmlSqlInjectionConfiguration extends TaintTracking::C
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
|
||||
guard instanceof ContainsSanitizer or guard instanceof EqualsSanitizer
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(MethodAccess ma |
|
||||
ma.getMethod().getDeclaringType() instanceof MapType and
|
||||
ma.getMethod().getName() = "get" and
|
||||
ma.getQualifier() = node1.asExpr() and
|
||||
ma = node2.asExpr()
|
||||
)
|
||||
or
|
||||
exists(MethodAccess ma |
|
||||
ma.getMethod().getDeclaringType() instanceof TypeObject and
|
||||
ma.getMethod().getName() = "toString" and
|
||||
ma.getQualifier() = node1.asExpr() and
|
||||
ma = node2.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from
|
||||
@@ -42,7 +59,7 @@ from
|
||||
XMLElement xmle
|
||||
where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
isSqlInjection(sink.getNode(), xmle)
|
||||
isMapperXmlSqlInjection(sink.getNode(), xmle)
|
||||
select sink.getNode(), source, sink,
|
||||
"MyBatis Mapper XML sql injection might include code from $@ to $@.", source.getNode(),
|
||||
"this user input", xmle, "this sql operation"
|
||||
|
||||
@@ -1,56 +1,16 @@
|
||||
import java
|
||||
import MyBatisCommonLib
|
||||
import semmle.code.xml.MyBatisMapperXML
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.frameworks.MyBatis
|
||||
import semmle.code.java.frameworks.Properties
|
||||
|
||||
private predicate propertiesKey(DataFlow::Node prop, string key) {
|
||||
exists(MethodAccess m |
|
||||
m.getMethod() instanceof PropertiesSetPropertyMethod and
|
||||
key = m.getArgument(0).(CompileTimeConstantExpr).getStringValue() and
|
||||
prop.asExpr() = m.getQualifier()
|
||||
)
|
||||
}
|
||||
|
||||
private class PropertiesFlowConfig extends DataFlow2::Configuration {
|
||||
PropertiesFlowConfig() { this = "PropertiesFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node src) {
|
||||
exists(MethodAccess ma | ma.getMethod() instanceof IbatisConfigurationGetVariablesMethod |
|
||||
src.asExpr() = ma
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { propertiesKey(sink, _) }
|
||||
}
|
||||
|
||||
/** Get the key value of Mybatis Configuration Variable. */
|
||||
private string getAnMybatisConfigurationVariableKey() {
|
||||
exists(PropertiesFlowConfig conf, DataFlow::Node n |
|
||||
propertiesKey(n, result) and
|
||||
conf.hasFlow(_, n)
|
||||
)
|
||||
}
|
||||
|
||||
/** The interface `org.apache.ibatis.annotations.Param`. */
|
||||
private class TypeParam extends Interface {
|
||||
TypeParam() { this.hasQualifiedName("org.apache.ibatis.annotations", "Param") }
|
||||
}
|
||||
|
||||
/** A reference type that extends a parameterization of `java.util.List`. */
|
||||
private class ListType extends RefType {
|
||||
ListType() {
|
||||
this.getSourceDeclaration().getASourceSupertype*().hasQualifiedName("java.util", "List")
|
||||
}
|
||||
}
|
||||
|
||||
/** A sink for MyBatis Mapper method call an argument. */
|
||||
class MyBatisMapperMethodCallAnArgument extends DataFlow::Node {
|
||||
MyBatisMapperMethodCallAnArgument() {
|
||||
exists(MyBatisMapperSqlOperation mbmxe, MethodAccess mc |
|
||||
mbmxe.getMapperMethod() = mc.getMethod()
|
||||
exists(MyBatisMapperSqlOperation mbmxe, MethodAccess ma |
|
||||
mbmxe.getMapperMethod() = ma.getMethod()
|
||||
|
|
||||
mc.getAnArgument() = this.asExpr()
|
||||
ma.getAnArgument() = this.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -60,23 +20,7 @@ private string getAnMybatiXmlSetValue(XMLElement xmle) {
|
||||
result = xmle.getTextValue().trim().regexpFind("(#|\\$)(\\{([^\\}]*\\}))", _, _)
|
||||
}
|
||||
|
||||
predicate isSqlInjection(DataFlow::Node node, XMLElement xmle) {
|
||||
// MyBatis Mapper method parameter name sql injection vulnerabilities.
|
||||
// e.g. MyBatis Mapper method: `void test(String name);` and MyBatis Mapper XML file:`select id,name from test where name like '%${name}%'`
|
||||
exists(MyBatisMapperSqlOperation mbmxe, MyBatisMapperSql mbms, MethodAccess mc, int i |
|
||||
mbmxe.getMapperMethod() = mc.getMethod()
|
||||
|
|
||||
(
|
||||
mbmxe.getAChild*() = xmle
|
||||
or
|
||||
mbmxe.getInclude().getRefid() = mbms.getId() and
|
||||
mbms.getAChild*() = xmle
|
||||
) and
|
||||
not mc.getMethod().getParameter(i).hasAnnotation() and
|
||||
getAnMybatiXmlSetValue(xmle).matches("${" + mc.getMethod().getParameter(i).getName() + "%}") and
|
||||
mc.getArgument(i) = node.asExpr()
|
||||
)
|
||||
or
|
||||
predicate isMapperXmlSqlInjection(DataFlow::Node node, XMLElement xmle) {
|
||||
// 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}`
|
||||
exists(
|
||||
@@ -120,10 +64,12 @@ predicate isSqlInjection(DataFlow::Node node, XMLElement xmle) {
|
||||
// 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}%'`
|
||||
exists(
|
||||
MyBatisMapperSqlOperation mbmxe, MyBatisMapperSql mbms, MethodAccess mc, int i, string res
|
||||
MyBatisMapperSqlOperation mbmxe, MyBatisMapperForeach mbmf, MyBatisMapperSql mbms,
|
||||
MethodAccess mc, int i, string res
|
||||
|
|
||||
mbmxe.getMapperMethod() = mc.getMethod()
|
||||
|
|
||||
mbmf = xmle and
|
||||
(
|
||||
mbmxe.getAChild*() = xmle
|
||||
or
|
||||
@@ -142,7 +88,7 @@ predicate isSqlInjection(DataFlow::Node node, XMLElement xmle) {
|
||||
mc.getArgument(i) = node.asExpr()
|
||||
)
|
||||
or
|
||||
// MyBatis Mapper method string type sql injection vulnerabilities.
|
||||
// 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}%'`
|
||||
exists(MyBatisMapperSqlOperation mbmxe, MyBatisMapperSql mbms, MethodAccess mc, string res |
|
||||
mbmxe.getMapperMethod() = mc.getMethod()
|
||||
@@ -154,11 +100,33 @@ predicate isSqlInjection(DataFlow::Node node, XMLElement xmle) {
|
||||
mbms.getAChild*() = xmle
|
||||
) and
|
||||
res = getAnMybatiXmlSetValue(xmle) and
|
||||
mc.getMethod().getAParamType() instanceof TypeString and
|
||||
mc.getMethod().getNumberOfParameters() = 1 and
|
||||
not mc.getMethod().getAParameter().hasAnnotation() and
|
||||
res.matches("%${%}") and
|
||||
not res.matches("${" + getAnMybatisConfigurationVariableKey() + "}") and
|
||||
mc.getAnArgument() = node.asExpr()
|
||||
)
|
||||
or
|
||||
// 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}%'`
|
||||
exists(
|
||||
MyBatisMapperSqlOperation mbmxe, MyBatisMapperSql mbms, MethodAccess mc, int i, string res
|
||||
|
|
||||
mbmxe.getMapperMethod() = mc.getMethod()
|
||||
|
|
||||
(
|
||||
mbmxe.getAChild*() = xmle
|
||||
or
|
||||
mbmxe.getInclude().getRefid() = mbms.getId() and
|
||||
mbms.getAChild*() = xmle
|
||||
) and
|
||||
not mc.getMethod().getParameter(i).hasAnnotation() and
|
||||
res = getAnMybatiXmlSetValue(xmle) and
|
||||
(
|
||||
res.matches("%${param" + (i + 1) + "%}")
|
||||
or
|
||||
res.matches("%${arg" + i + "%}")
|
||||
) and
|
||||
mc.getArgument(i) = node.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ abstract class MyBatisMapperSqlOperation extends MyBatisMapperXMLElement {
|
||||
*/
|
||||
MyBatisMapperInclude getInclude() { result = getAChild*() }
|
||||
|
||||
|
||||
Method getMapperMethod() {
|
||||
result.getName() = this.getId() and
|
||||
result.getDeclaringType() = this.getParent().(MyBatisMapperXMLElement).getNamespaceRefType()
|
||||
@@ -117,3 +116,10 @@ class MyBatisMapperInclude extends MyBatisMapperXMLElement {
|
||||
*/
|
||||
string getRefid() { result = getAttribute("refid").getValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `<foreach>` element in a `MyBatisMapperXMLElement`.
|
||||
*/
|
||||
class MyBatisMapperForeach extends MyBatisMapperXMLElement {
|
||||
MyBatisMapperForeach() { getName() = "foreach" }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
edges
|
||||
| MybatisSqlInjection.java:62:19:62:43 | name : String | MybatisSqlInjection.java:63:35:63:38 | name : String |
|
||||
| MybatisSqlInjection.java:63:35:63:38 | name : String | MybatisSqlInjectionService.java:48:19:48:29 | name : String |
|
||||
| MybatisSqlInjectionService.java:48:19:48:29 | name : String | MybatisSqlInjectionService.java:50:23:50:26 | name : String |
|
||||
| MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [<map.value>] : String | MybatisSqlInjectionService.java:51:27:51:33 | hashMap |
|
||||
| MybatisSqlInjectionService.java:50:23:50:26 | name : String | MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [<map.value>] : String |
|
||||
nodes
|
||||
| MybatisSqlInjection.java:62:19:62:43 | name : String | semmle.label | name : String |
|
||||
| MybatisSqlInjection.java:63:35:63:38 | name : String | semmle.label | name : String |
|
||||
| MybatisSqlInjectionService.java:48:19:48:29 | name : String | semmle.label | name : String |
|
||||
| MybatisSqlInjectionService.java:50:3:50:9 | hashMap [post update] [<map.value>] : String | semmle.label | hashMap [post update] [<map.value>] : String |
|
||||
| MybatisSqlInjectionService.java:50:23:50:26 | name : String | semmle.label | name : String |
|
||||
| MybatisSqlInjectionService.java:51:27:51:33 | hashMap | semmle.label | hashMap |
|
||||
subpaths
|
||||
#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 |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-089/MyBatisAnnotationSqlInjection.ql
|
||||
@@ -1,31 +1,31 @@
|
||||
edges
|
||||
| MybatisSqlInjection.java:19:25:19:49 | name : String | MybatisSqlInjection.java:20:55:20:58 | name : String |
|
||||
| MybatisSqlInjection.java:20:55:20:58 | name : String | MybatisSqlInjectionService.java:12:25:12:35 | name : String |
|
||||
| MybatisSqlInjection.java:20:55:20:58 | name : String | MybatisSqlInjectionService.java:13:25:13:35 | name : String |
|
||||
| MybatisSqlInjection.java:25:25:25:49 | name : String | MybatisSqlInjection.java:26:55:26:58 | name : String |
|
||||
| MybatisSqlInjection.java:26:55:26:58 | name : String | MybatisSqlInjectionService.java:17:25:17:35 | name : String |
|
||||
| MybatisSqlInjection.java:26:55:26:58 | name : String | MybatisSqlInjectionService.java:18:25:18:35 | name : String |
|
||||
| MybatisSqlInjection.java:31:25:31:49 | test : Test | MybatisSqlInjection.java:32:55:32:58 | test : Test |
|
||||
| MybatisSqlInjection.java:32:55:32:58 | test : Test | MybatisSqlInjectionService.java:22:25:22:33 | test : Test |
|
||||
| MybatisSqlInjection.java:32:55:32:58 | test : Test | MybatisSqlInjectionService.java:23:25:23:33 | test : Test |
|
||||
| MybatisSqlInjection.java:37:19:37:40 | test : Test | MybatisSqlInjection.java:38:35:38:38 | test : Test |
|
||||
| MybatisSqlInjection.java:38:35:38:38 | test : Test | MybatisSqlInjectionService.java:27:19:27:27 | test : Test |
|
||||
| MybatisSqlInjection.java:38:35:38:38 | test : Test | MybatisSqlInjectionService.java:28:19:28:27 | test : Test |
|
||||
| MybatisSqlInjection.java:42:19:42:40 | test : Test | MybatisSqlInjection.java:43:35:43:38 | test : Test |
|
||||
| MybatisSqlInjection.java:43:35:43:38 | test : Test | MybatisSqlInjectionService.java:31:19:31:27 | test : Test |
|
||||
| MybatisSqlInjection.java:43:35:43:38 | test : Test | MybatisSqlInjectionService.java:32:19:32:27 | test : Test |
|
||||
| MybatisSqlInjection.java:47:19:47:57 | params : Map | MybatisSqlInjection.java:48:35:48:40 | params : Map |
|
||||
| MybatisSqlInjection.java:48:35:48:40 | params : Map | MybatisSqlInjectionService.java:35:19:35:44 | params : Map |
|
||||
| MybatisSqlInjection.java:48:35:48:40 | params : Map | MybatisSqlInjectionService.java:36:19:36:44 | params : Map |
|
||||
| MybatisSqlInjection.java:52:19:52:50 | params : List | MybatisSqlInjection.java:53:35:53:40 | params : List |
|
||||
| MybatisSqlInjection.java:53:35:53:40 | params : List | MybatisSqlInjectionService.java:39:19:39: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:58:35:58:40 | params : String[] | MybatisSqlInjectionService.java:43:19:43:33 | params : String[] |
|
||||
| MybatisSqlInjection.java:68:26:68:36 | name : String | MybatisSqlInjection.java:69:56:69:59 | name : String |
|
||||
| MybatisSqlInjection.java:69:56:69:59 | name : String | MybatisSqlInjectionService.java:52:26:52:36 | name : String |
|
||||
| MybatisSqlInjectionService.java:12:25:12:35 | name : String | MybatisSqlInjectionService.java:13:47:13:50 | name |
|
||||
| MybatisSqlInjectionService.java:17:25:17:35 | name : String | MybatisSqlInjectionService.java:18:47:18:50 | name |
|
||||
| MybatisSqlInjectionService.java:22:25:22:33 | test : Test | MybatisSqlInjectionService.java:23:47:23:50 | test |
|
||||
| MybatisSqlInjectionService.java:27:19:27:27 | test : Test | MybatisSqlInjectionService.java:28:27:28:30 | test |
|
||||
| MybatisSqlInjectionService.java:31:19:31:27 | test : Test | MybatisSqlInjectionService.java:32:27:32:30 | test |
|
||||
| MybatisSqlInjectionService.java:35:19:35:44 | params : Map | MybatisSqlInjectionService.java:36:27:36:32 | params |
|
||||
| MybatisSqlInjectionService.java:39:19:39:37 | params : List | MybatisSqlInjectionService.java:40:27:40:32 | params |
|
||||
| MybatisSqlInjectionService.java:43:19:43:33 | params : String[] | MybatisSqlInjectionService.java:44:27:44:32 | params |
|
||||
| MybatisSqlInjectionService.java:52:26:52:36 | name : String | MybatisSqlInjectionService.java:53:48:53:51 | name |
|
||||
| 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: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:28:19:28:27 | test : Test | MybatisSqlInjectionService.java:29:27:29:30 | test |
|
||||
| MybatisSqlInjectionService.java:32:19:32:27 | test : Test | MybatisSqlInjectionService.java:33:27:33:30 | test |
|
||||
| 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: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
|
||||
| MybatisSqlInjection.java:19:25:19:49 | name : String | semmle.label | name : String |
|
||||
| MybatisSqlInjection.java:20:55:20:58 | name : String | semmle.label | name : String |
|
||||
@@ -43,33 +43,34 @@ nodes
|
||||
| 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:58:35:58:40 | params : String[] | semmle.label | params : String[] |
|
||||
| MybatisSqlInjection.java:68:26:68:36 | name : String | semmle.label | name : String |
|
||||
| MybatisSqlInjection.java:69:56:69:59 | name : String | semmle.label | name : String |
|
||||
| MybatisSqlInjectionService.java:12:25:12:35 | name : String | semmle.label | name : String |
|
||||
| MybatisSqlInjectionService.java:13:47:13:50 | name | semmle.label | name |
|
||||
| MybatisSqlInjectionService.java:17:25:17:35 | name : String | semmle.label | name : String |
|
||||
| MybatisSqlInjectionService.java:18:47:18:50 | name | semmle.label | name |
|
||||
| MybatisSqlInjectionService.java:22:25:22:33 | test : Test | semmle.label | test : Test |
|
||||
| MybatisSqlInjectionService.java:23:47:23:50 | test | semmle.label | test |
|
||||
| MybatisSqlInjectionService.java:27:19:27:27 | test : Test | semmle.label | test : Test |
|
||||
| MybatisSqlInjectionService.java:28:27:28:30 | test | semmle.label | test |
|
||||
| MybatisSqlInjectionService.java:31:19:31:27 | test : Test | semmle.label | test : Test |
|
||||
| MybatisSqlInjectionService.java:32:27:32:30 | test | semmle.label | test |
|
||||
| MybatisSqlInjectionService.java:35:19:35:44 | params : Map | semmle.label | params : Map |
|
||||
| MybatisSqlInjectionService.java:36:27:36:32 | params | semmle.label | params |
|
||||
| MybatisSqlInjectionService.java:39:19:39:37 | params : List | semmle.label | params : List |
|
||||
| MybatisSqlInjectionService.java:40:27:40:32 | params | semmle.label | params |
|
||||
| MybatisSqlInjectionService.java:43:19:43:33 | params : String[] | semmle.label | params : String[] |
|
||||
| MybatisSqlInjectionService.java:44:27:44:32 | params | semmle.label | params |
|
||||
| MybatisSqlInjectionService.java:52:26:52:36 | name : String | semmle.label | name : String |
|
||||
| MybatisSqlInjectionService.java:53:48:53:51 | name | semmle.label | name |
|
||||
| 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:14:47:14:50 | name | semmle.label | name |
|
||||
| MybatisSqlInjectionService.java:18:25:18:35 | name : String | semmle.label | name : String |
|
||||
| MybatisSqlInjectionService.java:19:47:19:50 | name | semmle.label | name |
|
||||
| MybatisSqlInjectionService.java:23:25:23:33 | test : Test | semmle.label | test : Test |
|
||||
| MybatisSqlInjectionService.java:24:47:24:50 | test | semmle.label | test |
|
||||
| MybatisSqlInjectionService.java:28:19:28:27 | test : Test | semmle.label | test : Test |
|
||||
| MybatisSqlInjectionService.java:29:27:29:30 | test | semmle.label | test |
|
||||
| MybatisSqlInjectionService.java:32:19:32:27 | test : Test | semmle.label | test : Test |
|
||||
| MybatisSqlInjectionService.java:33:27:33:30 | test | semmle.label | test |
|
||||
| MybatisSqlInjectionService.java:36:19:36:44 | params : Map | semmle.label | params : Map |
|
||||
| MybatisSqlInjectionService.java:37:27:37:32 | params | semmle.label | params |
|
||||
| MybatisSqlInjectionService.java:40:19:40:37 | params : List | semmle.label | params : List |
|
||||
| MybatisSqlInjectionService.java:41:27:41:32 | params | semmle.label | params |
|
||||
| MybatisSqlInjectionService.java:44:19:44:33 | params : String[] | semmle.label | params : String[] |
|
||||
| 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
|
||||
#select
|
||||
| MybatisSqlInjectionService.java:13:47:13:50 | name | MybatisSqlInjection.java:19:25:19:49 | name : String | MybatisSqlInjectionService.java:13:47:13: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:18:47:18:50 | name | MybatisSqlInjection.java:25:25:25:49 | name : String | MybatisSqlInjectionService.java:18:47:18: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:23:47:23:50 | test | MybatisSqlInjection.java:31:25:31:49 | test : Test | MybatisSqlInjectionService.java:23:47:23: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:28:27:28:30 | test | MybatisSqlInjection.java:37:19:37:40 | test : Test | MybatisSqlInjectionService.java:28:27:28: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:32:27:32:30 | test | MybatisSqlInjection.java:42:19:42:40 | test : Test | MybatisSqlInjectionService.java:32:27:32: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:32:27:32:30 | test | MybatisSqlInjection.java:42:19:42:40 | test : Test | MybatisSqlInjectionService.java:32:27:32: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:36:27:36:32 | params | MybatisSqlInjection.java:47:19:47:57 | params : Map | MybatisSqlInjectionService.java:36:27:36: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:40:27:40:32 | params | MybatisSqlInjection.java:52:19:52:50 | params : List | MybatisSqlInjectionService.java:40:27:40: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:44:27:44:32 | params | MybatisSqlInjection.java:57:19:57:46 | params : String[] | MybatisSqlInjectionService.java:44:27:44: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: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: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: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: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: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 |
|
||||
|
||||
@@ -58,6 +58,11 @@ public class MybatisSqlInjection {
|
||||
mybatisSqlInjectionService.bad8(params);
|
||||
}
|
||||
|
||||
@GetMapping(value = "msi9")
|
||||
public void bad9(@RequestParam String name) {
|
||||
mybatisSqlInjectionService.bad9(name);
|
||||
}
|
||||
|
||||
@GetMapping(value = "good1")
|
||||
public List<Test> good1(Integer id) {
|
||||
List<Test> result = mybatisSqlInjectionService.good1(id);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -44,6 +45,12 @@ public class MybatisSqlInjectionService {
|
||||
sqlInjectionMapper.bad8(params);
|
||||
}
|
||||
|
||||
public void bad9(String name) {
|
||||
HashMap hashMap = new HashMap();
|
||||
hashMap.put("name", name);
|
||||
sqlInjectionMapper.bad9(hashMap);
|
||||
}
|
||||
|
||||
public List<Test> good1(Integer id) {
|
||||
List<Test> result = sqlInjectionMapper.good1(id);
|
||||
return result;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
@Mapper
|
||||
@Repository
|
||||
@@ -24,6 +26,9 @@ public interface SqlInjectionMapper {
|
||||
|
||||
void bad8(String[] params);
|
||||
|
||||
@Select({"select * from test", "where id = ${name}"})
|
||||
public Test bad9(HashMap<String, Object> map);
|
||||
|
||||
List<Test> good1(Integer id);
|
||||
|
||||
List<Test> good2(String name);
|
||||
|
||||
14
java/ql/test/stubs/org.mybatis-3.5.4/org/apache/ibatis/annotations/Select.java
generated
Normal file
14
java/ql/test/stubs/org.mybatis-3.5.4/org/apache/ibatis/annotations/Select.java
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
package org.apache.ibatis.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface Select {
|
||||
String[] value();
|
||||
}
|
||||
Reference in New Issue
Block a user