1
+ /** Definitions for the Static Initialization Vector query. */
2
+
1
3
import java
2
4
import semmle.code.java.dataflow.TaintTracking
3
5
import semmle.code.java.dataflow.TaintTracking2
@@ -9,15 +11,14 @@ private predicate initializedWithConstants(ArrayCreationExpr array) {
9
11
// creating an array without an initializer, for example `new byte[8]`
10
12
not exists ( array .getInit ( ) )
11
13
or
12
- // creating a multidimensional array with an initializer like `{ new byte[8], new byte[16] }`
13
- // This works around https://github.com/github/codeql/issues/6552 -- change me once there is
14
- // a better way to distinguish nested initializers that create zero-filled arrays
15
- // (e.g. `new byte[1]`) from those with an initializer list (`new byte[] { 1 }` or just `{ 1 }`)
16
- array .getInit ( ) .getAnInit ( ) .getAChildExpr ( ) instanceof IntegerLiteral
17
- or
18
- // creating an array wit an initializer like `new byte[] { 1, 2 }`
19
- forex ( Expr element | element = array .getInit ( ) .getAnInit ( ) |
14
+ initializedWithConstantsHelper ( array .getInit ( ) )
15
+ }
16
+
17
+ private predicate initializedWithConstantsHelper ( ArrayInit arInit ) {
18
+ forex ( Expr element | element = arInit .getAnInit ( ) |
20
19
element instanceof CompileTimeConstantExpr
20
+ or
21
+ initializedWithConstantsHelper ( element )
21
22
)
22
23
}
23
24
@@ -74,9 +75,7 @@ private class ArrayUpdateConfig extends TaintTracking2::Configuration {
74
75
source .asExpr ( ) instanceof StaticByteArrayCreation
75
76
}
76
77
77
- override predicate isSink ( DataFlow:: Node sink ) {
78
- exists ( ArrayUpdate update | update .getArray ( ) = sink .asExpr ( ) )
79
- }
78
+ override predicate isSink ( DataFlow:: Node sink ) { sink .asExpr ( ) = any ( ArrayUpdate upd ) .getArray ( ) }
80
79
}
81
80
82
81
/**
@@ -85,29 +84,12 @@ private class ArrayUpdateConfig extends TaintTracking2::Configuration {
85
84
private class StaticInitializationVectorSource extends DataFlow:: Node {
86
85
StaticInitializationVectorSource ( ) {
87
86
exists ( StaticByteArrayCreation array | array = this .asExpr ( ) |
88
- not exists ( ArrayUpdateConfig config | config .hasFlow ( DataFlow2:: exprNode ( array ) , _) )
89
- )
90
- }
91
- }
92
-
93
- /**
94
- * A config that tracks initialization of a cipher for encryption.
95
- */
96
- private class EncryptionModeConfig extends TaintTracking2:: Configuration {
97
- EncryptionModeConfig ( ) { this = "EncryptionModeConfig" }
98
-
99
- override predicate isSource ( DataFlow:: Node source ) {
100
- source
101
- .asExpr ( )
102
- .( FieldRead )
103
- .getField ( )
104
- .hasQualifiedName ( "javax.crypto" , "Cipher" , "ENCRYPT_MODE" )
105
- }
106
-
107
- override predicate isSink ( DataFlow:: Node sink ) {
108
- exists ( MethodAccess ma , Method m | m = ma .getMethod ( ) |
109
- m .hasQualifiedName ( "javax.crypto" , "Cipher" , "init" ) and
110
- ma .getArgument ( 0 ) = sink .asExpr ( )
87
+ not exists ( ArrayUpdateConfig config | config .hasFlow ( DataFlow2:: exprNode ( array ) , _) ) and
88
+ // Reduce FPs from utility methods that return an empty array in an exceptional case
89
+ not exists ( ReturnStmt ret |
90
+ array .getADimension ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) = 0 and
91
+ DataFlow:: localExprFlow ( array , ret .getResult ( ) )
92
+ )
111
93
)
112
94
}
113
95
}
@@ -117,13 +99,14 @@ private class EncryptionModeConfig extends TaintTracking2::Configuration {
117
99
*/
118
100
private class EncryptionInitializationSink extends DataFlow:: Node {
119
101
EncryptionInitializationSink ( ) {
120
- exists ( MethodAccess ma , Method m , EncryptionModeConfig config | m = ma .getMethod ( ) |
102
+ exists ( MethodAccess ma , Method m , FieldRead fr | m = ma .getMethod ( ) |
121
103
m .hasQualifiedName ( "javax.crypto" , "Cipher" , "init" ) and
122
104
m .getParameterType ( 2 )
123
105
.( RefType )
124
106
.hasQualifiedName ( "java.security.spec" , "AlgorithmParameterSpec" ) and
125
- ma .getArgument ( 2 ) = this .asExpr ( ) and
126
- config .hasFlowToExpr ( ma .getArgument ( 0 ) )
107
+ fr .getField ( ) .hasQualifiedName ( "javax.crypto" , "Cipher" , "ENCRYPT_MODE" ) and
108
+ DataFlow:: localExprFlow ( fr , ma .getArgument ( 0 ) ) and
109
+ ma .getArgument ( 2 ) = this .asExpr ( )
127
110
)
128
111
}
129
112
}
0 commit comments