mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
Fix one
This commit is contained in:
@@ -44,12 +44,17 @@ private class MyBatisAnnotationSqlInjectionConfiguration extends TaintTracking::
|
||||
|
||||
from
|
||||
MyBatisAnnotationSqlInjectionConfiguration cfg, DataFlow::PathNode source,
|
||||
DataFlow::PathNode sink, IbatisSqlOperationAnnotation isoa, MethodAccess ma
|
||||
DataFlow::PathNode sink, IbatisSqlOperationAnnotation isoa, MethodAccess ma,
|
||||
string unsafeExpression
|
||||
where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
ma.getAnArgument() = sink.getNode().asExpr() and
|
||||
myBatisSqlOperationAnnotationFromMethod(ma.getMethod(), isoa) and
|
||||
isMybatisXmlOrAnnotationSqlInjection(sink.getNode(), ma, getAMybatisAnnotationSqlValue(isoa), _)
|
||||
unsafeExpression = getAMybatisAnnotationSqlValue(isoa) and
|
||||
(
|
||||
isMybatisXmlOrAnnotationSqlInjection(sink.getNode(), ma, unsafeExpression) or
|
||||
isMybatisAnnotationCollectionTypeSqlInjection(sink.getNode(), ma, unsafeExpression)
|
||||
)
|
||||
select sink.getNode(), source, sink,
|
||||
"MyBatis annotation SQL injection might include code from $@ to $@.", source.getNode(),
|
||||
"this user input", isoa, "this SQL operation"
|
||||
|
||||
@@ -44,7 +44,7 @@ class ListType extends RefType {
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if the specified method uses MyBatis Mapper XMLElement. */
|
||||
/** Holds if the specified `method` uses MyBatis Mapper XMLElement `mmxx`. */
|
||||
predicate myBatisMapperXMLElementFromMethod(Method method, MyBatisMapperXMLElement mmxx) {
|
||||
exists(MyBatisMapperSqlOperation mbmxe | mbmxe.getMapperMethod() = method |
|
||||
mbmxe.getAChild*() = mmxx
|
||||
@@ -56,7 +56,7 @@ predicate myBatisMapperXMLElementFromMethod(Method method, MyBatisMapperXMLEleme
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the specified method uses Ibatis Sql Operation Annotation. */
|
||||
/** Holds if the specified `method` has Ibatis Sql operation annotation `isoa`. */
|
||||
predicate myBatisSqlOperationAnnotationFromMethod(Method method, IbatisSqlOperationAnnotation isoa) {
|
||||
exists(MyBatisSqlOperationAnnotationMethod msoam |
|
||||
msoam = method and
|
||||
@@ -64,23 +64,80 @@ predicate myBatisSqlOperationAnnotationFromMethod(Method method, IbatisSqlOperat
|
||||
)
|
||||
}
|
||||
|
||||
/** Get the #{...} or ${...} parameters in the Mybatis mapper xml file. */
|
||||
/** Gets a `#{...}` or `${...}` expression argument in XML element `xmle`. */
|
||||
string getAMybatisXmlSetValue(XMLElement xmle) {
|
||||
result = xmle.getTextValue().regexpFind("(#|\\$)\\{[^\\}]*\\}", _, _)
|
||||
}
|
||||
|
||||
/** Get the #{...} or ${...} parameters in the Mybatis sql operation annotation value. */
|
||||
/** Gets a `#{...}` or `${...}` expression argument in annotation `isoa`. */
|
||||
string getAMybatisAnnotationSqlValue(IbatisSqlOperationAnnotation isoa) {
|
||||
result = isoa.getSqlValue().regexpFind("(#|\\$)\\{[^\\}]*\\}", _, _)
|
||||
}
|
||||
|
||||
/** Holds if it is SQL injection of MyBatis xml or MyBatis annotation. */
|
||||
bindingset[setValue]
|
||||
predicate isMybatisXmlOrAnnotationSqlInjection(
|
||||
//DataFlow::Node node, MyBatisMapperXMLElement xmle, IbatisSqlOperationAnnotation isoa
|
||||
DataFlow::Node node, MethodAccess ma, string setValue, MyBatisMapperXMLElement mmxe
|
||||
/** Holds if `node` is an argument to `ma` that is vulnerable to SQL injection attacks if `unsafeExpression` occurs in a MyBatis SQL expression. */
|
||||
bindingset[unsafeExpression]
|
||||
predicate isMybatisAnnotationCollectionTypeSqlInjection(
|
||||
DataFlow::Node node, MethodAccess ma, string unsafeExpression
|
||||
) {
|
||||
not setValue.regexpMatch("\\$\\{" + getAMybatisConfigurationVariableKey() + "\\}") and
|
||||
not unsafeExpression.regexpMatch("\\$\\{" + getAMybatisConfigurationVariableKey() + "\\}") and
|
||||
// The parameter type of the MyBatis 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(int i |
|
||||
not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
|
||||
(
|
||||
ma.getMethod().getParameterType(i) instanceof MapType or
|
||||
ma.getMethod().getParameterType(i) instanceof ListType or
|
||||
ma.getMethod().getParameterType(i) instanceof Array
|
||||
) and
|
||||
unsafeExpression.matches("${%}") and
|
||||
ma.getArgument(i) = node.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `node` is an argument to `ma` that is vulnerable to SQL injection attacks if `unsafeExpression` occurs in a MyBatis SQL expression. */
|
||||
bindingset[unsafeExpression]
|
||||
predicate isMybatisXmlCollectionTypeSqlInjection(
|
||||
DataFlow::Node node, MethodAccess ma, string unsafeExpression, MyBatisMapperXMLElement mmxe
|
||||
) {
|
||||
not unsafeExpression.regexpMatch("\\$\\{" + getAMybatisConfigurationVariableKey() + "\\}") and
|
||||
// The parameter type of the MyBatis method parameter is Map or List or Array.
|
||||
// SQL injection vulnerability caused by improper use of this parameter.
|
||||
// e.g.
|
||||
//
|
||||
// ```java
|
||||
// Test test(Map map);
|
||||
// <select id="test" resultMap="BaseResultMap">
|
||||
// select id,name from test where name in
|
||||
// <foreach collection="list" item="value" open="(" close=")" separator=",">
|
||||
// ${value}
|
||||
// </foreach>
|
||||
// </select>
|
||||
// ```
|
||||
exists(int i, MyBatisMapperForeach mbmf |
|
||||
mbmf = mmxe and
|
||||
not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
|
||||
(
|
||||
ma.getMethod().getParameterType(i) instanceof MapType or
|
||||
ma.getMethod().getParameterType(i) instanceof ListType or
|
||||
ma.getMethod().getParameterType(i) instanceof Array
|
||||
) and
|
||||
unsafeExpression.matches("${%}") and
|
||||
ma.getArgument(i) = node.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `node` is an argument to `ma` that is vulnerable to SQL injection attacks if `unsafeExpression` occurs in a MyBatis SQL expression. */
|
||||
bindingset[unsafeExpression]
|
||||
predicate isMybatisXmlOrAnnotationSqlInjection(
|
||||
DataFlow::Node node, MethodAccess ma, string unsafeExpression
|
||||
) {
|
||||
not unsafeExpression.regexpMatch("\\$\\{" + getAMybatisConfigurationVariableKey() + "\\}") and
|
||||
(
|
||||
// The method parameters use `@Param` annotation. Due to improper use of this parameter, SQL injection vulnerabilities are caused.
|
||||
// e.g.
|
||||
@@ -89,12 +146,12 @@ predicate isMybatisXmlOrAnnotationSqlInjection(
|
||||
// @Select(select id,name from test order by ${orderby,jdbcType=VARCHAR})
|
||||
// void test(@Param("orderby") String name);
|
||||
// ```
|
||||
exists(int i, Annotation annotation |
|
||||
setValue
|
||||
exists(Annotation annotation |
|
||||
unsafeExpression
|
||||
.matches("${" + annotation.getValue("value").(CompileTimeConstantExpr).getStringValue() +
|
||||
"%}") and
|
||||
annotation.getType() instanceof TypeParam and
|
||||
ma.getArgument(i) = node.asExpr()
|
||||
ma.getAnArgument() = node.asExpr()
|
||||
)
|
||||
or
|
||||
// MyBatis default parameter sql injection vulnerabilities.the default parameter form of the method is arg[0...n] or param[1...n].
|
||||
@@ -107,9 +164,9 @@ predicate isMybatisXmlOrAnnotationSqlInjection(
|
||||
exists(int i |
|
||||
not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
|
||||
(
|
||||
setValue.matches("${param" + (i + 1) + "%}")
|
||||
unsafeExpression.matches("${param" + (i + 1) + "%}")
|
||||
or
|
||||
setValue.matches("${arg" + i + "%}")
|
||||
unsafeExpression.matches("${arg" + i + "%}")
|
||||
) and
|
||||
ma.getArgument(i) = node.asExpr()
|
||||
)
|
||||
@@ -124,27 +181,7 @@ predicate isMybatisXmlOrAnnotationSqlInjection(
|
||||
exists(int i, RefType t |
|
||||
not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
|
||||
ma.getMethod().getParameterType(i).getName() = t.getName() and
|
||||
setValue.matches("${" + t.getAField().getName() + "%}") and
|
||||
ma.getArgument(i) = node.asExpr()
|
||||
)
|
||||
or
|
||||
// The parameter type of the MyBatis 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(int i, MyBatisMapperForeach mbmf |
|
||||
mbmf = mmxe and
|
||||
not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
|
||||
(
|
||||
ma.getMethod().getParameterType(i) instanceof MapType or
|
||||
ma.getMethod().getParameterType(i) instanceof ListType or
|
||||
ma.getMethod().getParameterType(i) instanceof Array
|
||||
) and
|
||||
setValue.matches("${%}") and
|
||||
unsafeExpression.matches("${" + t.getAField().getName() + "%}") and
|
||||
ma.getArgument(i) = node.asExpr()
|
||||
)
|
||||
or
|
||||
@@ -160,7 +197,7 @@ predicate isMybatisXmlOrAnnotationSqlInjection(
|
||||
exists(int i | i = 1 |
|
||||
ma.getMethod().getNumberOfParameters() = i and
|
||||
not ma.getMethod().getAParameter().getAnAnnotation().getType() instanceof TypeParam and
|
||||
setValue.matches("${%}") and
|
||||
unsafeExpression.matches("${%}") and
|
||||
ma.getAnArgument() = node.asExpr()
|
||||
)
|
||||
)
|
||||
|
||||
@@ -45,12 +45,16 @@ private class MyBatisMapperXmlSqlInjectionConfiguration extends TaintTracking::C
|
||||
|
||||
from
|
||||
MyBatisMapperXmlSqlInjectionConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink,
|
||||
MyBatisMapperXMLElement mmxe, MethodAccess ma
|
||||
MyBatisMapperXMLElement mmxe, MethodAccess ma, string unsafeExpression
|
||||
where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
ma.getAnArgument() = sink.getNode().asExpr() and
|
||||
myBatisMapperXMLElementFromMethod(ma.getMethod(), mmxe) and
|
||||
isMybatisXmlOrAnnotationSqlInjection(sink.getNode(), ma, getAMybatisXmlSetValue(mmxe), mmxe)
|
||||
unsafeExpression = getAMybatisXmlSetValue(mmxe) and
|
||||
(
|
||||
isMybatisXmlOrAnnotationSqlInjection(sink.getNode(), ma, unsafeExpression) or
|
||||
isMybatisXmlCollectionTypeSqlInjection(sink.getNode(), ma, unsafeExpression, mmxe)
|
||||
)
|
||||
select sink.getNode(), source, sink,
|
||||
"MyBatis Mapper XML SQL injection might include code from $@ to $@.", source.getNode(),
|
||||
"this user input", mmxe, "this SQL operation"
|
||||
|
||||
Reference in New Issue
Block a user