@@ -30,7 +30,7 @@ private class PropertiesFlowConfig extends DataFlow2::Configuration {
30
30
}
31
31
32
32
/** Get the key value of Mybatis Configuration Variable. */
33
- string getAnMybatisConfigurationVariableKey ( ) {
33
+ string getAMybatisConfigurationVariableKey ( ) {
34
34
exists ( PropertiesFlowConfig conf , DataFlow:: Node n |
35
35
propertiesKey ( n , result ) and
36
36
conf .hasFlowTo ( n )
@@ -44,134 +44,124 @@ class ListType extends RefType {
44
44
}
45
45
}
46
46
47
- /** Gets a call to the MyBatis mapper xml method. */
48
- MethodAccess getMyBatisMapperXmlMethodAccess ( XMLElement xmle ) {
49
- exists ( MyBatisMapperSqlOperation mbmxe |
50
- mbmxe .getMapperMethod ( ) = result .getMethod ( ) and
51
- (
52
- mbmxe .getAChild * ( ) = xmle
53
- or
54
- exists ( MyBatisMapperSql mbms |
55
- mbmxe .getInclude ( ) .getRefid ( ) = mbms .getId ( ) and
56
- mbms .getAChild * ( ) = xmle
57
- )
47
+ /** Holds if the specified method uses MyBatis Mapper XMLElement. */
48
+ predicate myBatisMapperXMLElementFromMethod ( Method method , MyBatisMapperXMLElement mmxx ) {
49
+ exists ( MyBatisMapperSqlOperation mbmxe | mbmxe .getMapperMethod ( ) = method |
50
+ mbmxe .getAChild * ( ) = mmxx
51
+ or
52
+ exists ( MyBatisMapperSql mbms |
53
+ mbmxe .getInclude ( ) .getRefid ( ) = mbms .getId ( ) and
54
+ mbms .getAChild * ( ) = mmxx
58
55
)
59
56
)
60
57
}
61
58
62
- /** Gets a call to the MyBatis SQL operation annotation method . */
63
- MethodAccess getMyBatisSqlOperationAnnotationMethodAccess ( IbatisSqlOperationAnnotation isoa ) {
59
+ /** Holds if the specified method uses Ibatis Sql Operation Annotation . */
60
+ predicate myBatisSqlOperationAnnotationFromMethod ( Method method , IbatisSqlOperationAnnotation isoa ) {
64
61
exists ( MyBatisSqlOperationAnnotationMethod msoam |
65
- msoam = result . getMethod ( ) and
62
+ msoam = method and
66
63
msoam .getAnAnnotation ( ) = isoa
67
64
)
68
65
}
69
66
70
67
/** Get the #{...} or ${...} parameters in the Mybatis mapper xml file. */
71
- private string getAnMybatisXmlSetValue ( XMLElement xmle ) {
72
- result = xmle .getTextValue ( ) .trim ( ) . regexpFind ( "(#|\\$)\\{[^\\}]*\\}" , _, _)
68
+ string getAMybatisXmlSetValue ( XMLElement xmle ) {
69
+ result = xmle .getTextValue ( ) .regexpFind ( "(#|\\$)\\{[^\\}]*\\}" , _, _)
73
70
}
74
71
75
72
/** Get the #{...} or ${...} parameters in the Mybatis sql operation annotation value. */
76
- private string getAMybatisAnnotationSqlValue ( IbatisSqlOperationAnnotation isoa ) {
77
- result = isoa .getSqlValue ( ) .trim ( ) . regexpFind ( "(#|\\$)\\{[^\\}]*\\}" , _, _)
73
+ string getAMybatisAnnotationSqlValue ( IbatisSqlOperationAnnotation isoa ) {
74
+ result = isoa .getSqlValue ( ) .regexpFind ( "(#|\\$)\\{[^\\}]*\\}" , _, _)
78
75
}
79
76
80
77
/** Holds if it is SQL injection of MyBatis xml or MyBatis annotation. */
78
+ bindingset [ setValue]
81
79
predicate isMybatisXmlOrAnnotationSqlInjection (
82
- DataFlow:: Node node , XMLElement xmle , IbatisSqlOperationAnnotation isoa
80
+ //DataFlow::Node node, MyBatisMapperXMLElement xmle, IbatisSqlOperationAnnotation isoa
81
+ DataFlow:: Node node , MethodAccess ma , string setValue , MyBatisMapperXMLElement mmxe
83
82
) {
84
- exists ( MethodAccess ma , string setValue |
85
- (
86
- ma = getMyBatisMapperXmlMethodAccess ( xmle ) and
87
- setValue = getAnMybatisXmlSetValue ( xmle )
88
- or
89
- ma = getMyBatisSqlOperationAnnotationMethodAccess ( isoa ) and
90
- setValue = getAMybatisAnnotationSqlValue ( isoa )
91
- ) and
92
- not setValue .regexpMatch ( "\\$\\{" + getAnMybatisConfigurationVariableKey ( ) + "\\}" ) and
93
- (
94
- // The method parameters use `@Param` annotation. Due to improper use of this parameter, SQL injection vulnerabilities are caused.
95
- // e.g.
96
- //
97
- // ```java
98
- // @Select(select id,name from test order by ${orderby,jdbcType=VARCHAR})
99
- // void test(@Param("orderby") String name);
100
- // ```
101
- exists ( int i , Annotation annotation |
102
- setValue
103
- .matches ( "%${" + annotation .getValue ( "value" ) .( CompileTimeConstantExpr ) .getStringValue ( )
104
- + "%}" ) and
105
- annotation .getType ( ) instanceof TypeParam and
106
- ma .getArgument ( i ) = node .asExpr ( )
107
- )
108
- or
109
- // MyBatis default parameter sql injection vulnerabilities.the default parameter form of the method is arg[0...n] or param[1...n].
110
- // e.g.
111
- //
112
- // ```java
113
- // @Select(select id,name from test order by ${arg0,jdbcType=VARCHAR})
114
- // void test(String name);
115
- // ```
116
- exists ( int i |
117
- not ma .getMethod ( ) .getParameter ( i ) .getAnAnnotation ( ) .getType ( ) instanceof TypeParam and
118
- (
119
- setValue .matches ( "%${param" + ( i + 1 ) + "%}" )
120
- or
121
- setValue .matches ( "%${arg" + i + "%}" )
122
- ) and
123
- not setValue = "${" + getAnMybatisConfigurationVariableKey ( ) + "}" and
124
- ma .getArgument ( i ) = node .asExpr ( )
125
- )
126
- or
127
- // SQL injection vulnerability caused by improper use of MyBatis instance class fields.
128
- // e.g.
129
- //
130
- // ```java
131
- // @Select(select id,name from test order by ${name,jdbcType=VARCHAR})
132
- // void test(Test test);
133
- // ```
134
- exists ( int i , RefType t |
135
- not ma .getMethod ( ) .getParameter ( i ) .getAnAnnotation ( ) .getType ( ) instanceof TypeParam and
136
- ma .getMethod ( ) .getParameterType ( i ) .getName ( ) = t .getName ( ) and
137
- setValue .matches ( "%${" + t .getAField ( ) .getName ( ) + "%}" ) and
138
- ma .getArgument ( i ) = node .asExpr ( )
139
- )
140
- or
141
- // The parameter type of the MyBatis method parameter is Map or List or Array.
142
- // SQL injection vulnerability caused by improper use of this parameter.
143
- // e.g.
144
- //
145
- // ```java
146
- // @Select(select id,name from test where name like '%${value}%')
147
- // Test test(Map map);
148
- // ```
149
- exists ( int i , MyBatisMapperForeach mbmf |
150
- mbmf = xmle and
151
- not ma .getMethod ( ) .getParameter ( i ) .getAnAnnotation ( ) .getType ( ) instanceof TypeParam and
152
- (
153
- ma .getMethod ( ) .getParameterType ( i ) instanceof MapType or
154
- ma .getMethod ( ) .getParameterType ( i ) instanceof ListType or
155
- ma .getMethod ( ) .getParameterType ( i ) instanceof Array
156
- ) and
157
- setValue .matches ( "%${%}" ) and
158
- ma .getArgument ( i ) = node .asExpr ( )
159
- )
160
- or
161
- // This method has only one parameter and the parameter is not annotated with `@Param`.
162
- // Improper use of this parameter has a SQL injection vulnerability.
163
- // e.g.
164
- //
165
- // ```java
166
- // @Select(select id,name from test where name like '%${value}%')
167
- // Test test(String name);
168
- // ```
169
- exists ( int i | i = 1 |
170
- ma .getMethod ( ) .getNumberOfParameters ( ) = i and
171
- not ma .getMethod ( ) .getAParameter ( ) .getAnAnnotation ( ) .getType ( ) instanceof TypeParam and
172
- setValue .matches ( "%${%}" ) and
173
- ma .getAnArgument ( ) = node .asExpr ( )
174
- )
83
+ not setValue .regexpMatch ( "\\$\\{" + getAMybatisConfigurationVariableKey ( ) + "\\}" ) and
84
+ (
85
+ // The method parameters use `@Param` annotation. Due to improper use of this parameter, SQL injection vulnerabilities are caused.
86
+ // e.g.
87
+ //
88
+ // ```java
89
+ // @Select(select id,name from test order by ${orderby,jdbcType=VARCHAR})
90
+ // void test(@Param("orderby") String name);
91
+ // ```
92
+ exists ( int i , Annotation annotation |
93
+ setValue
94
+ .matches ( "${" + annotation .getValue ( "value" ) .( CompileTimeConstantExpr ) .getStringValue ( ) +
95
+ "%}" ) and
96
+ annotation .getType ( ) instanceof TypeParam and
97
+ ma .getArgument ( i ) = node .asExpr ( )
98
+ )
99
+ or
100
+ // MyBatis default parameter sql injection vulnerabilities.the default parameter form of the method is arg[0...n] or param[1...n].
101
+ // e.g.
102
+ //
103
+ // ```java
104
+ // @Select(select id,name from test order by ${arg0,jdbcType=VARCHAR})
105
+ // void test(String name);
106
+ // ```
107
+ exists ( int i |
108
+ not ma .getMethod ( ) .getParameter ( i ) .getAnAnnotation ( ) .getType ( ) instanceof TypeParam and
109
+ (
110
+ setValue .matches ( "${param" + ( i + 1 ) + "%}" )
111
+ or
112
+ setValue .matches ( "${arg" + i + "%}" )
113
+ ) and
114
+ ma .getArgument ( i ) = node .asExpr ( )
115
+ )
116
+ or
117
+ // SQL injection vulnerability caused by improper use of MyBatis instance class fields.
118
+ // e.g.
119
+ //
120
+ // ```java
121
+ // @Select(select id,name from test order by ${name,jdbcType=VARCHAR})
122
+ // void test(Test test);
123
+ // ```
124
+ exists ( int i , RefType t |
125
+ not ma .getMethod ( ) .getParameter ( i ) .getAnAnnotation ( ) .getType ( ) instanceof TypeParam and
126
+ ma .getMethod ( ) .getParameterType ( i ) .getName ( ) = t .getName ( ) and
127
+ setValue .matches ( "${" + t .getAField ( ) .getName ( ) + "%}" ) and
128
+ ma .getArgument ( i ) = node .asExpr ( )
129
+ )
130
+ or
131
+ // The parameter type of the MyBatis method parameter is Map or List or Array.
132
+ // SQL injection vulnerability caused by improper use of this parameter.
133
+ // e.g.
134
+ //
135
+ // ```java
136
+ // @Select(select id,name from test where name like '%${value}%')
137
+ // Test test(Map map);
138
+ // ```
139
+ exists ( int i , MyBatisMapperForeach mbmf |
140
+ mbmf = mmxe and
141
+ not ma .getMethod ( ) .getParameter ( i ) .getAnAnnotation ( ) .getType ( ) instanceof TypeParam and
142
+ (
143
+ ma .getMethod ( ) .getParameterType ( i ) instanceof MapType or
144
+ ma .getMethod ( ) .getParameterType ( i ) instanceof ListType or
145
+ ma .getMethod ( ) .getParameterType ( i ) instanceof Array
146
+ ) and
147
+ setValue .matches ( "${%}" ) and
148
+ ma .getArgument ( i ) = node .asExpr ( )
149
+ )
150
+ or
151
+ // This method has only one parameter and the parameter is not annotated with `@Param`. The parameter can be named arbitrarily in the SQL statement.
152
+ // If the number of method variables is greater than one, they cannot be named arbitrarily.
153
+ // Improper use of this parameter has a SQL injection vulnerability.
154
+ // e.g.
155
+ //
156
+ // ```java
157
+ // @Select(select id,name from test where name like '%${value}%')
158
+ // Test test(String name);
159
+ // ```
160
+ exists ( int i | i = 1 |
161
+ ma .getMethod ( ) .getNumberOfParameters ( ) = i and
162
+ not ma .getMethod ( ) .getAParameter ( ) .getAnAnnotation ( ) .getType ( ) instanceof TypeParam and
163
+ setValue .matches ( "${%}" ) and
164
+ ma .getAnArgument ( ) = node .asExpr ( )
175
165
)
176
166
)
177
167
}
0 commit comments