Skip to content

Commit 8ee4184

Browse files
committed
consider blankspace / comma /dot field
1 parent b0c86d8 commit 8ee4184

File tree

4 files changed

+14
-11
lines changed

4 files changed

+14
-11
lines changed

java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ bindingset[unsafeExpression]
8686
predicate isMybatisCollectionTypeSqlInjection(
8787
DataFlow::Node node, MethodAccess ma, string unsafeExpression
8888
) {
89-
not unsafeExpression.regexpMatch("\\$\\{" + getAMybatisConfigurationVariableKey() + "\\}") and
89+
not unsafeExpression.regexpMatch("\\$\\{\\s*" + getAMybatisConfigurationVariableKey() + "\\s*\\}") and
9090
// The parameter type of the MyBatis method parameter is Map or List or Array.
9191
// SQL injection vulnerability caused by improper use of this parameter.
9292
// e.g.
@@ -120,19 +120,22 @@ bindingset[unsafeExpression]
120120
predicate isMybatisXmlOrAnnotationSqlInjection(
121121
DataFlow::Node node, MethodAccess ma, string unsafeExpression
122122
) {
123-
not unsafeExpression.regexpMatch("\\$\\{" + getAMybatisConfigurationVariableKey() + "\\}") and
123+
not unsafeExpression.regexpMatch("\\$\\{\\s*" + getAMybatisConfigurationVariableKey() + "\\s*\\}") and
124124
(
125125
// The method parameters use `@Param` annotation. Due to improper use of this parameter, SQL injection vulnerabilities are caused.
126126
// e.g.
127127
//
128128
// ```java
129129
// @Select(select id,name from test order by ${orderby,jdbcType=VARCHAR})
130130
// void test(@Param("orderby") String name);
131+
//
132+
// @Select(select id,name from test where name = ${ user . name })
133+
// void test(@Param("user") User u);
131134
// ```
132135
exists(Annotation annotation |
133136
unsafeExpression
134-
.matches("${" + annotation.getValue("value").(CompileTimeConstantExpr).getStringValue() +
135-
"%}") and
137+
.regexpMatch("\\$\\{\\s*" + annotation.getValue("value").(CompileTimeConstantExpr).getStringValue() +
138+
"\\b[^}]*?\\}") and
136139
annotation.getType() instanceof TypeParam and
137140
ma.getAnArgument() = node.asExpr() and
138141
annotation.getTarget() =
@@ -150,11 +153,11 @@ predicate isMybatisXmlOrAnnotationSqlInjection(
150153
exists(int i |
151154
not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
152155
(
153-
unsafeExpression.matches("${param" + (i + 1) + "%}")
156+
unsafeExpression.regexpMatch("\\$\\{\\s*param" + (i + 1) + "\\b[^}]*?\\}")
154157
or
155-
unsafeExpression.matches("${arg" + i + "%}")
158+
unsafeExpression.regexpMatch("\\$\\{\\s*arg" + i + "\\b[^}]*?\\}")
156159
or
157-
unsafeExpression.regexpMatch("\\$\\{\\s*" + ma.getMethod().getParameter(i).getName() + "\\s*(,.*?)?\\s*\\}")
160+
unsafeExpression.regexpMatch("\\$\\{\\s*" + ma.getMethod().getParameter(i).getName() + "\\b[^}]*?\\}")
158161
) and
159162
ma.getArgument(i) = node.asExpr()
160163
)
@@ -169,7 +172,7 @@ predicate isMybatisXmlOrAnnotationSqlInjection(
169172
exists(int i, RefType t |
170173
not ma.getMethod().getParameter(i).getAnAnnotation().getType() instanceof TypeParam and
171174
ma.getMethod().getParameterType(i).getName() = t.getName() and
172-
unsafeExpression.matches("${" + t.getAField().getName() + "%}") and
175+
unsafeExpression.regexpMatch("\\$\\{\\s*" + t.getAField().getName() + "\\b[^}]*?\\}") and
173176
ma.getArgument(i) = node.asExpr()
174177
)
175178
or

java/ql/test/experimental/query-tests/security/CWE-089/src/main/MyBatisAnnotationSqlInjection.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ nodes
4242
subpaths
4343
#select
4444
| 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:33:2:33:54 | Select | this SQL operation |
45-
| MybatisSqlInjectionService.java:55:32:55:35 | name | MybatisSqlInjection.java:67:46:67:70 | name : String | MybatisSqlInjectionService.java:55:32:55:35 | name | MyBatis annotation SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:67:46:67:70 | name | this user input | SqlInjectionMapper.java:36:2:36:70 | Select | this SQL operation |
45+
| MybatisSqlInjectionService.java:55:32:55:35 | name | MybatisSqlInjection.java:67:46:67:70 | name : String | MybatisSqlInjectionService.java:55:32:55:35 | name | MyBatis annotation SQL injection might include code from $@ to $@. | MybatisSqlInjection.java:67:46:67:70 | name | this user input | SqlInjectionMapper.java:36:2:36:72 | Select | this SQL operation |

java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public interface SqlInjectionMapper {
3333
@Select({"select * from test", "where id = ${name}"})
3434
public Test bad9(HashMap<String, Object> map);
3535

36-
@Select({"select * from test where id = #{id} and name = '${name}'"})
36+
@Select({"select * from test where id = #{id} and name = '${ name }'"})
3737
String bad10(Integer id, String name);
3838

3939
List<Test> good1(Integer id);

java/ql/test/experimental/query-tests/security/CWE-089/src/main/SqlInjectionMapper.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<sql id="Update_By_Example_Where_Clause">
1313
<where>
1414
<if test="test.name != null">
15-
and name = ${test.name,jdbcType=VARCHAR}
15+
and name = ${ test . name , jdbcType = VARCHAR }
1616
</if>
1717
<if test="test.id != null">
1818
and id = #{test.id}

0 commit comments

Comments
 (0)