@@ -4,124 +4,111 @@ import semmle.code.java.dataflow.DataFlow
4
4
private import semmle.code.java.dataflow.TaintTracking
5
5
import semmle.code.java.dataflow.FlowSources
6
6
7
+ abstract class Source extends DataFlow:: Node {
8
+ Source ( ) { this = this }
9
+ }
7
10
8
- // a static string of an unsafe executable tainting arg 0 of Runtime.exec()
9
- class ExecTaintConfiguration extends TaintTracking:: Configuration {
10
- ExecTaintConfiguration ( ) { this = "ExecTaintConfiguration" }
11
-
12
- override
13
- predicate
14
- isSource ( DataFlow:: Node source ) {
15
- source .asExpr ( ) instanceof StringLiteral
16
- and source .asExpr ( ) .( StringLiteral ) .getValue ( ) instanceof UnSafeExecutable
11
+ module RuntimeExec {
12
+ // a static string of an unsafe executable tainting arg 0 of Runtime.exec()
13
+ module RuntimeExecConfiguration implements DataFlow:: ConfigSig {
14
+ predicate isSource ( DataFlow:: Node source ) {
15
+ source .asExpr ( ) instanceof StringLiteral and
16
+ source .asExpr ( ) .( StringLiteral ) .getValue ( ) instanceof UnSafeExecutable
17
17
}
18
18
19
- override
20
- predicate
21
- isSink ( DataFlow:: Node sink ) {
22
- exists ( RuntimeExecMethod method , MethodAccess call |
23
- call .getMethod ( ) = method
24
- and sink .asExpr ( ) = call .getArgument ( 0 )
25
- and sink .asExpr ( ) .getType ( ) instanceof Array
26
- )
19
+ predicate isSink ( DataFlow:: Node sink ) {
20
+ exists ( RuntimeExecMethod method , MethodCall call |
21
+ call .getMethod ( ) = method and
22
+ sink .asExpr ( ) = call .getArgument ( 0 ) and
23
+ sink .asExpr ( ) .getType ( ) instanceof Array
24
+ )
27
25
}
28
26
29
- override
30
- predicate
31
- isSanitizer ( DataFlow:: Node node ) {
32
- node .asExpr ( ) .getFile ( ) .isSourceFile ( ) and
33
- (
34
- node instanceof AssignToNonZeroIndex
35
- or node instanceof ArrayInitAtNonZeroIndex
36
- or node instanceof StreamConcatAtNonZeroIndex
37
- or node .getType ( ) instanceof PrimitiveType
38
- or node .getType ( ) instanceof BoxedType
39
- )
27
+ predicate isBarrier ( DataFlow:: Node node ) {
28
+ node .asExpr ( ) .getFile ( ) .isSourceFile ( ) and
29
+ (
30
+ node instanceof AssignToNonZeroIndex or
31
+ node instanceof ArrayInitAtNonZeroIndex or
32
+ node instanceof StreamConcatAtNonZeroIndex or
33
+ node .getType ( ) instanceof PrimitiveType or
34
+ node .getType ( ) instanceof BoxedType
35
+ )
40
36
}
41
- }
37
+ }
42
38
43
- abstract class Source extends DataFlow:: Node {
44
- Source ( ) {
45
- this = this
46
- }
47
- }
39
+ module RuntimeExecFlow = TaintTracking:: Global< RuntimeExecConfiguration > ;
48
40
41
+ import RuntimeExecFlow:: PathGraph
42
+ }
49
43
50
44
// taint flow from user data to args of the command
51
- class ExecTaintConfiguration2 extends TaintTracking:: Configuration {
52
- ExecTaintConfiguration2 ( ) { this = "ExecTaintConfiguration2" }
53
-
54
- override
55
- predicate
56
- isSource ( DataFlow:: Node source ) {
57
- source instanceof Source
45
+ module ExecTaint {
46
+ module ExecTaintConfiguration implements DataFlow:: ConfigSig {
47
+ predicate isSource ( DataFlow:: Node source ) { source instanceof Source }
48
+
49
+ predicate isSink ( DataFlow:: Node sink ) {
50
+ exists ( RuntimeExecMethod method , MethodCall call , int index |
51
+ call .getMethod ( ) = method and
52
+ sink .asExpr ( ) = call .getArgument ( index ) and
53
+ sink .asExpr ( ) .getType ( ) instanceof Array
54
+ )
58
55
}
59
56
60
- override
61
- predicate
62
- isSink ( DataFlow:: Node sink ) {
63
- exists ( RuntimeExecMethod method , MethodAccess call , int index |
64
- call .getMethod ( ) = method
65
- and sink .asExpr ( ) = call .getArgument ( index )
66
- and sink .asExpr ( ) .getType ( ) instanceof Array
67
- )
57
+ predicate isBarrier ( DataFlow:: Node node ) {
58
+ node .asExpr ( ) .getFile ( ) .isSourceFile ( ) and
59
+ (
60
+ node .getType ( ) instanceof PrimitiveType or
61
+ node .getType ( ) instanceof BoxedType
62
+ )
68
63
}
64
+ }
69
65
70
- override
71
- predicate
72
- isSanitizer ( DataFlow:: Node node ) {
73
- node .asExpr ( ) .getFile ( ) .isSourceFile ( ) and
74
- (
75
- node .getType ( ) instanceof PrimitiveType
76
- or node .getType ( ) instanceof BoxedType
77
- )
78
- }
79
- }
66
+ module ExecTaintFlow = TaintTracking:: Global< ExecTaintConfiguration > ;
80
67
68
+ import ExecTaintFlow:: PathGraph
69
+ }
81
70
82
71
// array[3] = node
83
72
class AssignToNonZeroIndex extends DataFlow:: Node {
84
- AssignExpr assign ;
85
- ArrayAccess access ;
86
-
87
- AssignToNonZeroIndex ( ) {
88
- assign .getDest ( ) = access
89
- and access .getIndexExpr ( ) .( IntegerLiteral ) .getValue ( ) != "0"
90
- and assign .getSource ( ) = this .asExpr ( )
91
- }
73
+ AssignExpr assign ;
74
+ ArrayAccess access ;
75
+
76
+ AssignToNonZeroIndex ( ) {
77
+ assign .getDest ( ) = access and
78
+ access .getIndexExpr ( ) .( IntegerLiteral ) .getValue ( ) != "0" and
79
+ assign .getSource ( ) = this .asExpr ( )
80
+ }
92
81
}
93
82
94
-
95
83
// String[] array = {"a", "b, "c"};
96
84
class ArrayInitAtNonZeroIndex extends DataFlow:: Node {
97
- ArrayInit init ;
98
- int index ;
85
+ ArrayInit init ;
86
+ int index ;
99
87
100
- ArrayInitAtNonZeroIndex ( ) {
101
- init .getInit ( index ) = this .asExpr ( )
102
- and index != 0
103
- }
88
+ ArrayInitAtNonZeroIndex ( ) {
89
+ init .getInit ( index ) = this .asExpr ( ) and
90
+ index != 0
91
+ }
104
92
}
105
93
106
94
// Stream.concat(Arrays.stream(array_1), Arrays.stream(array_2))
107
95
class StreamConcatAtNonZeroIndex extends DataFlow:: Node {
108
- MethodAccess call ;
109
- int index ;
110
-
111
- StreamConcatAtNonZeroIndex ( ) {
112
- call .getMethod ( ) .getQualifiedName ( ) = "java.util.stream.Stream.concat"
113
- and call .getArgument ( index ) = this .asExpr ( )
114
- and index != 0
115
- }
96
+ MethodCall call ;
97
+ int index ;
98
+
99
+ StreamConcatAtNonZeroIndex ( ) {
100
+ call .getMethod ( ) .getQualifiedName ( ) = "java.util.stream.Stream.concat" and
101
+ call .getArgument ( index ) = this .asExpr ( ) and
102
+ index != 0
103
+ }
116
104
}
117
105
118
-
119
106
// allow list of executables that execute their arguments
120
107
// TODO: extend with data extensions
121
108
class UnSafeExecutable extends string {
122
- bindingset [ this ]
123
- UnSafeExecutable ( ) {
124
- this .regexpMatch ( "^(|.*/)([a-z]*sh|javac?|python[23]?|perl|[Pp]ower[Ss]hell|php|node|deno|bun|ruby|osascript|cmd|Rscript|groovy)(\\.exe)?$" )
125
- and not this .matches ( "netsh.exe" )
126
- }
109
+ bindingset [ this ]
110
+ UnSafeExecutable ( ) {
111
+ this .regexpMatch ( "^(|.*/)([a-z]*sh|javac?|python[23]?|perl|[Pp]ower[Ss]hell|php|node|deno|bun|ruby|osascript|cmd|Rscript|groovy)(\\.exe)?$" ) and
112
+ not this .matches ( "netsh.exe" )
113
+ }
127
114
}
0 commit comments