11
11
12
12
import java
13
13
import semmle.code.java.dataflow.FlowSources
14
+ import semmle.code.java.frameworks.spring.SpringController
14
15
import DataFlow:: PathGraph
15
16
16
17
/** The class `org.python.util.PythonInterpreter`. */
@@ -22,12 +23,7 @@ class PythonInterpreter extends RefType {
22
23
class InterpretExprMethod extends Method {
23
24
InterpretExprMethod ( ) {
24
25
this .getDeclaringType ( ) .getAnAncestor * ( ) instanceof PythonInterpreter and
25
- (
26
- getName ( ) .matches ( "exec%" ) or
27
- hasName ( "eval" ) or
28
- hasName ( "compile" ) or
29
- getName ( ) .matches ( "run%" )
30
- )
26
+ getName ( ) .matches ( [ "exec%" , "run%" , "eval" , "compile" ] )
31
27
}
32
28
}
33
29
@@ -48,14 +44,14 @@ predicate runCode(MethodAccess ma, Expr sink) {
48
44
class LoadClassMethod extends Method {
49
45
LoadClassMethod ( ) {
50
46
this .getDeclaringType ( ) .getAnAncestor * ( ) instanceof BytecodeLoader and
51
- (
52
- hasName ( "makeClass" ) or
53
- hasName ( "makeCode" )
54
- )
47
+ hasName ( [ "makeClass" , "makeCode" ] )
55
48
}
56
49
}
57
50
58
- /** Holds if a Java class file is loaded. */
51
+ /**
52
+ * Holds if `ma` is a call to a class-loading method, and `sink` is the byte array
53
+ * representing the class to be loaded.
54
+ */
59
55
predicate loadClass ( MethodAccess ma , Expr sink ) {
60
56
exists ( Method m , int i | m = ma .getMethod ( ) |
61
57
m instanceof LoadClassMethod and
@@ -69,7 +65,7 @@ class Py extends RefType {
69
65
Py ( ) { this .hasQualifiedName ( "org.python.core" , "Py" ) }
70
66
}
71
67
72
- /** A method that compiles code with `Py`. */
68
+ /** A method declared on class `Py` or one of its descendants that compiles Python code . */
73
69
class PyCompileMethod extends Method {
74
70
PyCompileMethod ( ) {
75
71
this .getDeclaringType ( ) .getAnAncestor * ( ) instanceof Py and
@@ -85,7 +81,7 @@ predicate compile(MethodAccess ma, Expr sink) {
85
81
)
86
82
}
87
83
88
- /** Sink of an expression loaded by Jython. */
84
+ /** An expression loaded by Jython. */
89
85
class CodeInjectionSink extends DataFlow:: ExprNode {
90
86
CodeInjectionSink ( ) {
91
87
runCode ( _, this .getExpr ( ) ) or
@@ -103,17 +99,18 @@ class CodeInjectionSink extends DataFlow::ExprNode {
103
99
class CodeInjectionConfiguration extends TaintTracking:: Configuration {
104
100
CodeInjectionConfiguration ( ) { this = "CodeInjectionConfiguration" }
105
101
106
- override predicate isSource ( DataFlow:: Node source ) {
107
- source instanceof RemoteFlowSource
108
- or
109
- source instanceof LocalUserInput
110
- }
102
+ override predicate isSource ( DataFlow:: Node source ) { source instanceof RemoteFlowSource }
111
103
112
104
override predicate isSink ( DataFlow:: Node sink ) { sink instanceof CodeInjectionSink }
113
105
114
106
override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
115
107
// @RequestBody MyQueryObj query; interpreter.exec(query.getInterpreterCode());
116
- exists ( MethodAccess ma | ma .getQualifier ( ) = node1 .asExpr ( ) and ma = node2 .asExpr ( ) )
108
+ exists ( MethodAccess ma |
109
+ ma .getMethod ( ) .getDeclaringType ( ) .getASubtype * ( ) instanceof SpringUntrustedDataType and
110
+ not ma .getMethod ( ) .getDeclaringType ( ) instanceof TypeObject and
111
+ ma .getQualifier ( ) = node1 .asExpr ( ) and
112
+ ma = node2 .asExpr ( )
113
+ )
117
114
}
118
115
}
119
116
0 commit comments