@@ -7,95 +7,100 @@ private class TypeParam extends Interface {
77 TypeParam ( ) { this .hasQualifiedName ( "org.apache.ibatis.annotations" , "Param" ) }
88}
99
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" )
3914 }
4015}
4116
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 ( )
5422 |
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 ( )
6924 )
7025 }
7126}
7227
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+ )
101106}
0 commit comments