@@ -3,108 +3,51 @@ import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions
3
3
import semmle.code.java.dataflow.DataFlow
4
4
import semmle.code.java.dataflow.FlowSources
5
5
6
- // a static string of an unsafe executable tainting arg 0 of Runtime.exec()
7
- deprecated class ExecTaintConfiguration extends TaintTracking:: Configuration {
8
- ExecTaintConfiguration ( ) { this = "ExecTaintConfiguration" }
9
-
10
- override predicate isSource ( DataFlow:: Node source ) {
11
- source .asExpr ( ) instanceof StringLiteral and
12
- source .asExpr ( ) .( StringLiteral ) .getValue ( ) instanceof UnSafeExecutable
13
- }
14
-
15
- override predicate isSink ( DataFlow:: Node sink ) {
16
- exists ( RuntimeExecMethod method , MethodAccess call |
17
- call .getMethod ( ) = method and
18
- sink .asExpr ( ) = call .getArgument ( 0 ) and
19
- sink .asExpr ( ) .getType ( ) instanceof Array
20
- )
21
- }
22
-
23
- override predicate isSanitizer ( DataFlow:: Node node ) {
24
- node .asExpr ( ) .getFile ( ) .isSourceFile ( ) and
25
- (
26
- node instanceof AssignToNonZeroIndex or
27
- node instanceof ArrayInitAtNonZeroIndex or
28
- node instanceof StreamConcatAtNonZeroIndex or
29
- node .getType ( ) instanceof PrimitiveType or
30
- node .getType ( ) instanceof BoxedType
31
- )
32
- }
33
- }
34
-
35
6
module ExecCmdFlowConfig implements DataFlow:: ConfigSig {
36
7
predicate isSource ( DataFlow:: Node source ) {
37
- source .asExpr ( ) instanceof StringLiteral and
38
- source .asExpr ( ) .( StringLiteral ) .getValue ( ) instanceof UnSafeExecutable
8
+ source .asExpr ( ) .( CompileTimeConstantExpr ) .getStringValue ( ) instanceof UnSafeExecutable
39
9
}
40
10
41
11
predicate isSink ( DataFlow:: Node sink ) {
42
- exists ( RuntimeExecMethod method , MethodAccess call |
43
- call .getMethod ( ) = method and
12
+ exists ( MethodAccess call |
13
+ call .getMethod ( ) instanceof RuntimeExecMethod and
44
14
sink .asExpr ( ) = call .getArgument ( 0 ) and
45
15
sink .asExpr ( ) .getType ( ) instanceof Array
46
16
)
47
17
}
48
18
49
19
predicate isBarrier ( DataFlow:: Node node ) {
50
- node .asExpr ( ) .getFile ( ) .isSourceFile ( ) and
51
- (
52
- node instanceof AssignToNonZeroIndex or
53
- node instanceof ArrayInitAtNonZeroIndex or
54
- node instanceof StreamConcatAtNonZeroIndex or
55
- node .getType ( ) instanceof PrimitiveType or
56
- node .getType ( ) instanceof BoxedType
57
- )
20
+ node instanceof AssignToNonZeroIndex or
21
+ node instanceof ArrayInitAtNonZeroIndex or
22
+ node instanceof StreamConcatAtNonZeroIndex or
23
+ node .getType ( ) instanceof PrimitiveType or
24
+ node .getType ( ) instanceof BoxedType
58
25
}
59
26
}
60
27
61
28
/** Tracks flow of unvalidated user input that is used in Runtime.Exec */
62
29
module ExecCmdFlow = TaintTracking:: Global< ExecCmdFlowConfig > ;
63
30
64
- abstract class Source extends DataFlow:: Node {
65
- Source ( ) { this = this }
66
- }
67
-
68
- // taint flow from user data to args of the command
69
- deprecated class ExecTaintConfiguration2 extends TaintTracking:: Configuration {
70
- ExecTaintConfiguration2 ( ) { this = "ExecTaintConfiguration2" }
31
+ abstract class Source extends DataFlow:: Node { }
71
32
72
- override predicate isSource ( DataFlow:: Node source ) { source instanceof Source }
73
-
74
- override predicate isSink ( DataFlow:: Node sink ) {
75
- exists ( RuntimeExecMethod method , MethodAccess call |
76
- call .getMethod ( ) = method and
77
- sink .asExpr ( ) = call .getArgument ( _) and
78
- sink .asExpr ( ) .getType ( ) instanceof Array
79
- )
80
- }
33
+ class RemoteSource extends Source instanceof RemoteFlowSource { }
81
34
82
- override predicate isSanitizer ( DataFlow:: Node node ) {
83
- node .asExpr ( ) .getFile ( ) .isSourceFile ( ) and
84
- (
85
- node .getType ( ) instanceof PrimitiveType or
86
- node .getType ( ) instanceof BoxedType
87
- )
88
- }
89
- }
35
+ class LocalSource extends Source instanceof LocalUserInput { }
90
36
91
37
module ExecUserFlowConfig implements DataFlow:: ConfigSig {
92
38
predicate isSource ( DataFlow:: Node source ) { source instanceof Source }
93
39
94
40
predicate isSink ( DataFlow:: Node sink ) {
95
- exists ( RuntimeExecMethod method , MethodAccess call |
96
- call .getMethod ( ) = method and
41
+ exists ( MethodAccess call |
42
+ call .getMethod ( ) instanceof RuntimeExecMethod and
97
43
sink .asExpr ( ) = call .getArgument ( _) and
98
44
sink .asExpr ( ) .getType ( ) instanceof Array
99
45
)
100
46
}
101
47
102
48
predicate isBarrier ( DataFlow:: Node node ) {
103
- node .asExpr ( ) .getFile ( ) .isSourceFile ( ) and
104
- (
105
- node .getType ( ) instanceof PrimitiveType or
106
- node .getType ( ) instanceof BoxedType
107
- )
49
+ node .getType ( ) instanceof PrimitiveType or
50
+ node .getType ( ) instanceof BoxedType
108
51
}
109
52
}
110
53
@@ -116,7 +59,7 @@ class AssignToNonZeroIndex extends DataFlow::Node {
116
59
AssignToNonZeroIndex ( ) {
117
60
exists ( AssignExpr assign , ArrayAccess access |
118
61
assign .getDest ( ) = access and
119
- access .getIndexExpr ( ) .( IntegerLiteral ) .getValue ( ) != "0" and
62
+ access .getIndexExpr ( ) .( IntegerLiteral ) .getValue ( ) . toInt ( ) != 0 and
120
63
assign .getSource ( ) = this .asExpr ( )
121
64
)
122
65
}
@@ -143,7 +86,7 @@ class StreamConcatAtNonZeroIndex extends DataFlow::Node {
143
86
}
144
87
}
145
88
146
- // allow list of executables that execute their arguments
89
+ // list of executables that execute their arguments
147
90
// TODO: extend with data extensions
148
91
class UnSafeExecutable extends string {
149
92
bindingset [ this ]
@@ -154,17 +97,15 @@ class UnSafeExecutable extends string {
154
97
}
155
98
156
99
predicate callIsTaintedByUserInputAndDangerousCommand (
157
- MethodAccess call , ExecUserFlow:: PathNode source , ExecUserFlow:: PathNode sink ,
158
- DataFlow:: Node sourceCmd , DataFlow :: Node sinkCmd
100
+ ExecUserFlow:: PathNode source , ExecUserFlow:: PathNode sink , DataFlow :: Node sourceCmd ,
101
+ DataFlow:: Node sinkCmd
159
102
) {
160
- call . getMethod ( ) instanceof RuntimeExecMethod and
161
- // this is a command-accepting call to exec, e.g. rt.exec(new String[]{"/bin/sh", ...})
162
- (
103
+ exists ( MethodAccess call |
104
+ call . getMethod ( ) instanceof RuntimeExecMethod and
105
+ // this is a command-accepting call to exec, e.g. rt.exec(new String[]{"/bin/sh", ...})
163
106
ExecCmdFlow:: flow ( sourceCmd , sinkCmd ) and
164
- sinkCmd .asExpr ( ) = call .getArgument ( 0 )
165
- ) and
166
- // it is tainted by untrusted user input
167
- (
107
+ sinkCmd .asExpr ( ) = call .getArgument ( 0 ) and
108
+ // it is tainted by untrusted user input
168
109
ExecUserFlow:: flowPath ( source , sink ) and
169
110
sink .getNode ( ) .asExpr ( ) = call .getArgument ( 0 )
170
111
)
0 commit comments