@@ -7,95 +7,100 @@ private class TypeParam extends Interface {
7
7
TypeParam ( ) { this .hasQualifiedName ( "org.apache.ibatis.annotations" , "Param" ) }
8
8
}
9
9
10
- /** A sink for MyBatis Mapper XML file sql injection vulnerabilities. */
11
- abstract class MyBatisMapperXmlSqlInjectionSink extends DataFlow:: Node { }
12
-
13
- /**
14
- * A sink for MyBatis Mapper method parameter name sql injection vulnerabilities.
15
- *
16
- * e.g. MyBatis Mapper method: `void test(String name);` and MyBatis Mapper XML file:`select id,name from test where name like '%${name}%'`
17
- */
18
- class MyBatisMapperParameterNameSqlInjectionSink extends MyBatisMapperXmlSqlInjectionSink {
19
- MyBatisMapperParameterNameSqlInjectionSink ( ) {
20
- exists (
21
- MyBatisMapperSqlOperation mbmxe , MyBatisMapperSql mbms , MethodAccess ma , int i , Method m ,
22
- Expr arg , string sql
23
- |
24
- m = ma .getMethod ( ) and arg = ma .getArgument ( i )
25
- |
26
- arg = this .asExpr ( ) and
27
- (
28
- mbmxe .getAChild * ( ) .getTextValue ( ) .trim ( ) = sql
29
- or
30
- mbmxe .getInclude ( ) .getRefid ( ) = mbms .getId ( ) and
31
- mbms .getAChild * ( ) .getTextValue ( ) .trim ( ) = sql
32
- ) and
33
- not m .getParameter ( i ) .hasAnnotation ( ) and
34
- sql .matches ( "%${" + m .getParameter ( i ) .getName ( ) + "%" ) and
35
- mbmxe .getId ( ) = ma .getMethod ( ) .getName ( ) and
36
- ma .getMethod ( ) .getDeclaringType ( ) =
37
- mbmxe .getParent ( ) .( MyBatisMapperXMLElement ) .getNamespaceRefType ( )
38
- )
10
+ /** A reference type that extends a parameterization of `java.util.List`. */
11
+ private class ListType extends RefType {
12
+ ListType ( ) {
13
+ this .getSourceDeclaration ( ) .getASourceSupertype * ( ) .hasQualifiedName ( "java.util" , "List" )
39
14
}
40
15
}
41
16
42
- /**
43
- * A sink for MyBatis Mapper method Param Annotation sql injection vulnerabilities.
44
- *
45
- * 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}`
46
- */
47
- class MyBatisMapperParamAnnotationSqlInjectionSink extends MyBatisMapperXmlSqlInjectionSink {
48
- MyBatisMapperParamAnnotationSqlInjectionSink ( ) {
49
- exists (
50
- MyBatisMapperSqlOperation mbmxe , MyBatisMapperSql mbms , MethodAccess ma , int i , Method m ,
51
- Expr arg , Annotation a , string sql
52
- |
53
- m = ma .getMethod ( ) and arg = ma .getArgument ( i )
17
+ /** A sink for MyBatis Mapper method call an argument. */
18
+ class MyBatisMapperMethodCallAnArgument extends DataFlow:: Node {
19
+ MyBatisMapperMethodCallAnArgument ( ) {
20
+ exists ( MyBatisMapperSqlOperation mbmxe , MethodAccess mc |
21
+ mbmxe .getMapperMethod ( ) = mc .getMethod ( )
54
22
|
55
- arg = this .asExpr ( ) and
56
- (
57
- mbmxe .getAChild * ( ) .getTextValue ( ) .trim ( ) = sql
58
- or
59
- mbmxe .getInclude ( ) .getRefid ( ) = mbms .getId ( ) and
60
- mbms .getAChild * ( ) .getTextValue ( ) .trim ( ) = sql
61
- ) and
62
- m .getParameter ( i ) .hasAnnotation ( ) and
63
- m .getParameter ( i ) .getAnAnnotation ( ) = a and
64
- a .getType ( ) instanceof TypeParam and
65
- sql .matches ( "%${" + a .getValue ( "value" ) .( CompileTimeConstantExpr ) .getStringValue ( ) + "%" ) and
66
- mbmxe .getId ( ) = ma .getMethod ( ) .getName ( ) and
67
- ma .getMethod ( ) .getDeclaringType ( ) =
68
- mbmxe .getParent ( ) .( MyBatisMapperXMLElement ) .getNamespaceRefType ( )
23
+ mc .getAnArgument ( ) = this .asExpr ( )
69
24
)
70
25
}
71
26
}
72
27
73
- /**
74
- * A sink for MyBatis Mapper method Class Field sql injection vulnerabilities.
75
- *
76
- * e.g. MyBatis Mapper method: `void test(Test test);` and MyBatis Mapper XML file:`select id,name from test order by ${name,jdbcType=VARCHAR}`
77
- */
78
- class MyBatisMapperClassFieldSqlInjectionSink extends MyBatisMapperXmlSqlInjectionSink {
79
- MyBatisMapperClassFieldSqlInjectionSink ( ) {
80
- exists (
81
- MyBatisMapperSqlOperation mbmxe , MyBatisMapperSql mbms , MethodAccess ma , int i , Method m ,
82
- Expr arg , string sql , Class c
83
- |
84
- m = ma .getMethod ( ) and arg = ma .getArgument ( i )
85
- |
86
- arg = this .asExpr ( ) and
87
- (
88
- mbmxe .getAChild * ( ) .getTextValue ( ) .trim ( ) = sql
89
- or
90
- mbmxe .getInclude ( ) .getRefid ( ) = mbms .getId ( ) and
91
- mbms .getAChild * ( ) .getTextValue ( ) .trim ( ) = sql
92
- ) and
93
- not m .getParameter ( i ) .hasAnnotation ( ) and
94
- m .getParameterType ( i ) .getName ( ) = c .getName ( ) and
95
- sql .matches ( "%${" + c .getAField ( ) .getName ( ) + "%" ) and
96
- mbmxe .getId ( ) = ma .getMethod ( ) .getName ( ) and
97
- ma .getMethod ( ) .getDeclaringType ( ) =
98
- mbmxe .getParent ( ) .( MyBatisMapperXMLElement ) .getNamespaceRefType ( )
99
- )
100
- }
28
+ predicate isSqlInjection ( DataFlow:: Node node , XMLElement xmle ) {
29
+ // MyBatis Mapper method parameter name sql injection vulnerabilities.
30
+ // e.g. MyBatis Mapper method: `void test(String name);` and MyBatis Mapper XML file:`select id,name from test where name like '%${name}%'`
31
+ exists ( MyBatisMapperSqlOperation mbmxe , MyBatisMapperSql mbms , MethodAccess mc , int i |
32
+ mbmxe .getMapperMethod ( ) = mc .getMethod ( )
33
+ |
34
+ (
35
+ mbmxe .getAChild * ( ) = xmle
36
+ or
37
+ mbmxe .getInclude ( ) .getRefid ( ) = mbms .getId ( ) and
38
+ mbms .getAChild * ( ) = xmle
39
+ ) and
40
+ not mc .getMethod ( ) .getParameter ( i ) .hasAnnotation ( ) and
41
+ xmle .getTextValue ( ) .trim ( ) .matches ( "%${" + mc .getMethod ( ) .getParameter ( i ) .getName ( ) + "%" ) and
42
+ mc .getArgument ( i ) = node .asExpr ( )
43
+ )
44
+ or
45
+ // MyBatis Mapper method Param Annotation sql injection vulnerabilities.
46
+ // 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}`
47
+ exists (
48
+ MyBatisMapperSqlOperation mbmxe , MyBatisMapperSql mbms , MethodAccess mc , int i ,
49
+ Annotation annotation
50
+ |
51
+ mbmxe .getMapperMethod ( ) = mc .getMethod ( )
52
+ |
53
+ (
54
+ mbmxe .getAChild * ( ) = xmle
55
+ or
56
+ mbmxe .getInclude ( ) .getRefid ( ) = mbms .getId ( ) and
57
+ mbms .getAChild * ( ) = xmle
58
+ ) and
59
+ mc .getMethod ( ) .getParameter ( i ) .hasAnnotation ( ) and
60
+ mc .getMethod ( ) .getParameter ( i ) .getAnAnnotation ( ) = annotation and
61
+ annotation .getType ( ) instanceof TypeParam and
62
+ xmle .getTextValue ( )
63
+ .trim ( )
64
+ .matches ( "%${" + annotation .getValue ( "value" ) .( CompileTimeConstantExpr ) .getStringValue ( ) +
65
+ "%" ) and
66
+ mc .getArgument ( i ) = node .asExpr ( )
67
+ )
68
+ or
69
+ // MyBatis Mapper method Class Field sql injection vulnerabilities.
70
+ // e.g. MyBatis Mapper method: `void test(Test test);` and MyBatis Mapper XML file:`select id,name from test order by ${name,jdbcType=VARCHAR}`
71
+ exists ( MyBatisMapperSqlOperation mbmxe , MyBatisMapperSql mbms , MethodAccess mc , int i , Class c |
72
+ mbmxe .getMapperMethod ( ) = mc .getMethod ( )
73
+ |
74
+ (
75
+ mbmxe .getAChild * ( ) = xmle
76
+ or
77
+ mbmxe .getInclude ( ) .getRefid ( ) = mbms .getId ( ) and
78
+ mbms .getAChild * ( ) = xmle
79
+ ) and
80
+ not mc .getMethod ( ) .getParameter ( i ) .hasAnnotation ( ) and
81
+ mc .getMethod ( ) .getParameterType ( i ) .getName ( ) = c .getName ( ) and
82
+ xmle .getTextValue ( ) .trim ( ) .matches ( "%${" + c .getAField ( ) .getName ( ) + "%" ) and
83
+ mc .getArgument ( i ) = node .asExpr ( )
84
+ )
85
+ or
86
+ // The parameter type of MyBatis Mapper method is Map or List or Array, which may cause SQL injection vulnerability.
87
+ // 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}%'`
88
+ exists ( MyBatisMapperSqlOperation mbmxe , MyBatisMapperSql mbms , MethodAccess mc , int i |
89
+ mbmxe .getMapperMethod ( ) = mc .getMethod ( )
90
+ |
91
+ (
92
+ mbmxe .getAChild * ( ) = xmle
93
+ or
94
+ mbmxe .getInclude ( ) .getRefid ( ) = mbms .getId ( ) and
95
+ mbms .getAChild * ( ) = xmle
96
+ ) and
97
+ not mc .getMethod ( ) .getParameter ( i ) .hasAnnotation ( ) and
98
+ (
99
+ mc .getMethod ( ) .getParameterType ( i ) instanceof MapType or
100
+ mc .getMethod ( ) .getParameterType ( i ) instanceof ListType or
101
+ mc .getMethod ( ) .getParameterType ( i ) instanceof Array
102
+ ) and
103
+ xmle .getTextValue ( ) .trim ( ) .matches ( "%${%" ) and
104
+ mc .getArgument ( i ) = node .asExpr ( )
105
+ )
101
106
}
0 commit comments