@@ -21,68 +21,132 @@ import semmle.code.java.frameworks.Guice
2121import semmle.code.java.frameworks.struts.StrutsActions
2222import semmle.code.java.frameworks.Thrift
2323
24- /** Class for `tainted` user input. */
25- abstract class UserInput extends DataFlow:: Node { }
26-
27- private predicate variableStep ( Expr tracked , VarAccess sink ) {
28- exists ( VariableAssign def |
29- def .getSource ( ) = tracked and
30- defUsePair ( def , sink )
31- )
24+ /** A data flow source of remote user input. */
25+ abstract class RemoteFlowSource extends DataFlow:: Node {
26+ /** Gets a string that describes the type of this remote flow source. */
27+ abstract string getSourceType ( ) ;
3228}
3329
34- /** Input that may be controlled by a remote user. */
35- class RemoteUserInput extends UserInput {
36- RemoteUserInput ( ) {
30+ private class RemoteTaintedMethodAccessSource extends RemoteFlowSource {
31+ RemoteTaintedMethodAccessSource ( ) {
3732 this .asExpr ( ) .( MethodAccess ) .getMethod ( ) instanceof RemoteTaintedMethod
38- or
39- // Parameters to RMI methods.
33+ }
34+
35+ override string getSourceType ( ) { result = "network data source" }
36+ }
37+
38+ private class RmiMethodParameterSource extends RemoteFlowSource {
39+ RmiMethodParameterSource ( ) {
4040 exists ( RemoteCallableMethod method |
4141 method .getAParameter ( ) = this .asParameter ( ) and
4242 (
4343 getType ( ) instanceof PrimitiveType or
4444 getType ( ) instanceof TypeString
4545 )
4646 )
47- or
48- // Parameters to Jax WS methods.
47+ }
48+
49+ override string getSourceType ( ) { result = "RMI method parameter" }
50+ }
51+
52+ private class JaxWsMethodParameterSource extends RemoteFlowSource {
53+ JaxWsMethodParameterSource ( ) {
4954 exists ( JaxWsEndpoint endpoint |
5055 endpoint .getARemoteMethod ( ) .getAParameter ( ) = this .asParameter ( )
5156 )
52- or
53- // Parameters to Jax Rs methods.
57+ }
58+
59+ override string getSourceType ( ) { result = "Jax WS method parameter" }
60+ }
61+
62+ private class JaxRsMethodParameterSource extends RemoteFlowSource {
63+ JaxRsMethodParameterSource ( ) {
5464 exists ( JaxRsResourceClass service |
5565 service .getAnInjectableCallable ( ) .getAParameter ( ) = this .asParameter ( ) or
5666 service .getAnInjectableField ( ) .getAnAccess ( ) = this .asExpr ( )
5767 )
58- or
59- // Reverse DNS. Try not to trigger on `localhost`.
68+ }
69+
70+ override string getSourceType ( ) { result = "Jax Rs method parameter" }
71+ }
72+
73+ private predicate variableStep ( Expr tracked , VarAccess sink ) {
74+ exists ( VariableAssign def |
75+ def .getSource ( ) = tracked and
76+ defUsePair ( def , sink )
77+ )
78+ }
79+
80+ private class ReverseDnsSource extends RemoteFlowSource {
81+ ReverseDnsSource ( ) {
82+ // Try not to trigger on `localhost`.
6083 exists ( MethodAccess m | m = this .asExpr ( ) |
6184 m .getMethod ( ) instanceof ReverseDNSMethod and
6285 not exists ( MethodAccess l |
6386 ( variableStep ( l , m .getQualifier ( ) ) or l = m .getQualifier ( ) ) and
6487 l .getMethod ( ) .getName ( ) = "getLocalHost"
6588 )
6689 )
67- or
68- //MessageBodyReader
90+ }
91+
92+ override string getSourceType ( ) { result = "reverse DNS lookup" }
93+ }
94+
95+ private class MessageBodyReaderParameterSource extends RemoteFlowSource {
96+ MessageBodyReaderParameterSource ( ) {
6997 exists ( MessageBodyReaderRead m |
7098 m .getParameter ( 4 ) = this .asParameter ( ) or
7199 m .getParameter ( 5 ) = this .asParameter ( )
72100 )
73- or
101+ }
102+
103+ override string getSourceType ( ) { result = "MessageBodyReader parameter" }
104+ }
105+
106+ private class SpringServletInputParameterSource extends RemoteFlowSource {
107+ SpringServletInputParameterSource ( ) {
74108 this .asParameter ( ) .getAnAnnotation ( ) instanceof SpringServletInputAnnotation
75- or
109+ }
110+
111+ override string getSourceType ( ) { result = "Spring servlet input parameter" }
112+ }
113+
114+ private class GuiceRequestParameterSource extends RemoteFlowSource {
115+ GuiceRequestParameterSource ( ) {
76116 exists ( GuiceRequestParametersAnnotation a |
77117 a = this .asParameter ( ) .getAnAnnotation ( ) or
78118 a = this .asExpr ( ) .( FieldRead ) .getField ( ) .getAnAnnotation ( )
79119 )
80- or
81- exists ( Struts2ActionSupportClass c | c .getASetterMethod ( ) .getField ( ) = this .asExpr ( ) .( FieldRead ) .getField ( ) )
82- or
120+ }
121+
122+ override string getSourceType ( ) { result = "Guice request parameter" }
123+ }
124+
125+ private class Struts2ActionSupportClassFieldReadSource extends RemoteFlowSource {
126+ Struts2ActionSupportClassFieldReadSource ( ) {
127+ exists ( Struts2ActionSupportClass c |
128+ c .getASetterMethod ( ) .getField ( ) = this .asExpr ( ) .( FieldRead ) .getField ( )
129+ )
130+ }
131+
132+ override string getSourceType ( ) { result = "Struts2 ActionSupport field" }
133+ }
134+
135+ private class ThriftIfaceParameterSource extends RemoteFlowSource {
136+ ThriftIfaceParameterSource ( ) {
83137 exists ( ThriftIface i | i .getAnImplementingMethod ( ) .getAParameter ( ) = this .asParameter ( ) )
84138 }
85139
140+ override string getSourceType ( ) { result = "Thrift Iface parameter" }
141+ }
142+
143+ /** Class for `tainted` user input. */
144+ abstract class UserInput extends DataFlow:: Node { }
145+
146+ /** Input that may be controlled by a remote user. */
147+ class RemoteUserInput extends UserInput {
148+ RemoteUserInput ( ) { this instanceof RemoteFlowSource }
149+
86150 /**
87151 * DEPRECATED: Use a configuration with a defined sink instead.
88152 *
0 commit comments