@@ -4,124 +4,111 @@ import semmle.code.java.dataflow.DataFlow
44private import semmle.code.java.dataflow.TaintTracking
55import semmle.code.java.dataflow.FlowSources
66
7+ abstract class Source extends DataFlow:: Node {
8+ Source ( ) { this = this }
9+ }
710
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
1717 }
1818
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+ )
2725 }
2826
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+ )
4036 }
41- }
37+ }
4238
43- abstract class Source extends DataFlow:: Node {
44- Source ( ) {
45- this = this
46- }
47- }
39+ module RuntimeExecFlow = TaintTracking:: Global< RuntimeExecConfiguration > ;
4840
41+ import RuntimeExecFlow:: PathGraph
42+ }
4943
5044// 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+ )
5855 }
5956
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+ )
6863 }
64+ }
6965
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 > ;
8067
68+ import ExecTaintFlow:: PathGraph
69+ }
8170
8271// array[3] = node
8372class 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+ }
9281}
9382
94-
9583// String[] array = {"a", "b, "c"};
9684class ArrayInitAtNonZeroIndex extends DataFlow:: Node {
97- ArrayInit init ;
98- int index ;
85+ ArrayInit init ;
86+ int index ;
9987
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+ }
10492}
10593
10694// Stream.concat(Arrays.stream(array_1), Arrays.stream(array_2))
10795class 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+ }
116104}
117105
118-
119106// allow list of executables that execute their arguments
120107// TODO: extend with data extensions
121108class 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+ }
127114}
0 commit comments