1111
1212import java
1313import semmle.code.java.dataflow.FlowSources
14+ import semmle.code.java.frameworks.spring.SpringController
1415import DataFlow:: PathGraph
1516
1617/** The class `org.python.util.PythonInterpreter`. */
@@ -22,12 +23,7 @@ class PythonInterpreter extends RefType {
2223class InterpretExprMethod extends Method {
2324 InterpretExprMethod ( ) {
2425 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" ] )
3127 }
3228}
3329
@@ -48,14 +44,14 @@ predicate runCode(MethodAccess ma, Expr sink) {
4844class LoadClassMethod extends Method {
4945 LoadClassMethod ( ) {
5046 this .getDeclaringType ( ) .getAnAncestor * ( ) instanceof BytecodeLoader and
51- (
52- hasName ( "makeClass" ) or
53- hasName ( "makeCode" )
54- )
47+ hasName ( [ "makeClass" , "makeCode" ] )
5548 }
5649}
5750
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+ */
5955predicate loadClass ( MethodAccess ma , Expr sink ) {
6056 exists ( Method m , int i | m = ma .getMethod ( ) |
6157 m instanceof LoadClassMethod and
@@ -69,7 +65,7 @@ class Py extends RefType {
6965 Py ( ) { this .hasQualifiedName ( "org.python.core" , "Py" ) }
7066}
7167
72- /** A method that compiles code with `Py`. */
68+ /** A method declared on class `Py` or one of its descendants that compiles Python code . */
7369class PyCompileMethod extends Method {
7470 PyCompileMethod ( ) {
7571 this .getDeclaringType ( ) .getAnAncestor * ( ) instanceof Py and
@@ -85,7 +81,7 @@ predicate compile(MethodAccess ma, Expr sink) {
8581 )
8682}
8783
88- /** Sink of an expression loaded by Jython. */
84+ /** An expression loaded by Jython. */
8985class CodeInjectionSink extends DataFlow:: ExprNode {
9086 CodeInjectionSink ( ) {
9187 runCode ( _, this .getExpr ( ) ) or
@@ -103,17 +99,18 @@ class CodeInjectionSink extends DataFlow::ExprNode {
10399class CodeInjectionConfiguration extends TaintTracking:: Configuration {
104100 CodeInjectionConfiguration ( ) { this = "CodeInjectionConfiguration" }
105101
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 }
111103
112104 override predicate isSink ( DataFlow:: Node sink ) { sink instanceof CodeInjectionSink }
113105
114106 override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
115107 // @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+ )
117114 }
118115}
119116
0 commit comments