@@ -39,21 +39,24 @@ private class DefaultLdapInjectionSinkModel extends SinkModelCsv {
3939 "groovy.util;Eval;false;x;(Object,String);;Argument[1];groovy" ,
4040 "groovy.util;Eval;false;xy;(Object,Object,String);;Argument[2];groovy" ,
4141 "groovy.util;Eval;false;xyz;(Object,Object,Object,String);;Argument[3];groovy" ,
42- "groovy.lang;GroovyClassLoader;false;parseClass;;;Argument[0];groovy"
42+ "groovy.lang;GroovyClassLoader;false;parseClass;;;Argument[0];groovy" ,
43+ "org.codehaus.groovy.control;CompilationUnit;false;compile;;;Argument[-1];groovy"
4344 ]
4445 }
4546}
4647
4748/** A set of additional taint steps to consider when taint tracking Groovy related data flows. */
4849private class DefaultGroovyInjectionAdditionalTaintStep extends GroovyInjectionAdditionalTaintStep {
4950 override predicate step ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
50- groovyCodeSourceTaintStep ( node1 , node2 )
51+ groovyCodeSourceTaintStep ( node1 , node2 ) or
52+ groovyCompilationUnitTaintStep ( node1 , node2 ) or
53+ groovySourceUnitTaintStep ( node1 , node2 )
5154 }
5255}
5356
5457/**
5558 * Holds if `fromNode` to `toNode` is a dataflow step from a tainted string to
56- * a `GroovyCodeSource` instance, i.e. `new GroovyCodeSource(tainted, ...)`.
59+ * a `GroovyCodeSource` instance by calling `new GroovyCodeSource(tainted, ...)`.
5760 */
5861private predicate groovyCodeSourceTaintStep ( DataFlow:: Node fromNode , DataFlow:: Node toNode ) {
5962 exists ( ConstructorCall gcscc |
@@ -63,7 +66,58 @@ private predicate groovyCodeSourceTaintStep(DataFlow::Node fromNode, DataFlow::N
6366 )
6467}
6568
69+ /**
70+ * Holds if `fromNode` to `toNode` is a dataflow step from a tainted string to
71+ * a `CompilationUnit` instance by calling `compilationUnit.addSource(..., tainted)`.
72+ */
73+ private predicate groovyCompilationUnitTaintStep ( DataFlow:: Node fromNode , DataFlow:: Node toNode ) {
74+ exists ( MethodAccess ma , Method m |
75+ ma .getMethod ( ) = m and
76+ m .hasName ( "addSource" ) and
77+ m .getDeclaringType ( ) instanceof TypeGroovyCompilationUnit
78+ |
79+ fromNode .asExpr ( ) = ma .getArgument ( ma .getNumArgument ( ) - 1 ) and
80+ toNode .asExpr ( ) = ma .getQualifier ( )
81+ )
82+ }
83+
84+ /**
85+ * Holds if `fromNode` to `toNode` is a dataflow step from a tainted string to
86+ * a `SourceUnit` instance by calling `new SourceUnit(..., tainted, ...)`
87+ * or `SourceUnit.create(..., tainted)`
88+ */
89+ private predicate groovySourceUnitTaintStep ( DataFlow:: Node fromNode , DataFlow:: Node toNode ) {
90+ exists ( ClassInstanceExpr cie , Argument arg |
91+ cie .getConstructedType ( ) instanceof TypeGroovySourceUnit and
92+ arg = cie .getArgument ( 1 ) and
93+ arg .getType ( ) instanceof TypeString
94+ |
95+ fromNode .asExpr ( ) = arg and
96+ toNode .asExpr ( ) = cie
97+ )
98+ or
99+ exists ( MethodAccess ma , Method m |
100+ ma .getMethod ( ) = m and
101+ m .hasName ( "create" ) and
102+ m .getDeclaringType ( ) instanceof TypeGroovySourceUnit
103+ |
104+ fromNode .asExpr ( ) = ma .getArgument ( 1 ) and toNode .asExpr ( ) = ma
105+ )
106+ }
107+
66108/** The class `groovy.lang.GroovyCodeSource`. */
67109private class TypeGroovyCodeSource extends RefType {
68110 TypeGroovyCodeSource ( ) { this .hasQualifiedName ( "groovy.lang" , "GroovyCodeSource" ) }
69111}
112+
113+ /** The class `org.codehaus.groovy.control.CompilationUnit`. */
114+ private class TypeGroovyCompilationUnit extends RefType {
115+ TypeGroovyCompilationUnit ( ) {
116+ this .hasQualifiedName ( "org.codehaus.groovy.control" , "CompilationUnit" )
117+ }
118+ }
119+
120+ /** The class `org.codehaus.groovy.control.CompilationUnit`. */
121+ private class TypeGroovySourceUnit extends RefType {
122+ TypeGroovySourceUnit ( ) { this .hasQualifiedName ( "org.codehaus.groovy.control" , "SourceUnit" ) }
123+ }
0 commit comments