1+ /** Definitions for the Static Initialization Vector query. */
2+
13import java
24import semmle.code.java.dataflow.TaintTracking
35import semmle.code.java.dataflow.TaintTracking2
@@ -9,15 +11,14 @@ private predicate initializedWithConstants(ArrayCreationExpr array) {
911 // creating an array without an initializer, for example `new byte[8]`
1012 not exists ( array .getInit ( ) )
1113 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 ( ) |
2019 element instanceof CompileTimeConstantExpr
20+ or
21+ initializedWithConstantsHelper ( element )
2122 )
2223}
2324
@@ -74,9 +75,7 @@ private class ArrayUpdateConfig extends TaintTracking2::Configuration {
7475 source .asExpr ( ) instanceof StaticByteArrayCreation
7576 }
7677
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 ( ) }
8079}
8180
8281/**
@@ -85,29 +84,12 @@ private class ArrayUpdateConfig extends TaintTracking2::Configuration {
8584private class StaticInitializationVectorSource extends DataFlow:: Node {
8685 StaticInitializationVectorSource ( ) {
8786 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+ )
11193 )
11294 }
11395}
@@ -117,13 +99,14 @@ private class EncryptionModeConfig extends TaintTracking2::Configuration {
11799 */
118100private class EncryptionInitializationSink extends DataFlow:: Node {
119101 EncryptionInitializationSink ( ) {
120- exists ( MethodAccess ma , Method m , EncryptionModeConfig config | m = ma .getMethod ( ) |
102+ exists ( MethodAccess ma , Method m , FieldRead fr | m = ma .getMethod ( ) |
121103 m .hasQualifiedName ( "javax.crypto" , "Cipher" , "init" ) and
122104 m .getParameterType ( 2 )
123105 .( RefType )
124106 .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 ( )
127110 )
128111 }
129112}
0 commit comments