4
4
5
5
import semmle.code.java.controlflow.Guards
6
6
import semmle.code.java.dataflow.TaintTracking
7
- import semmle.code.java.dataflow.TaintTracking2
8
- import semmle.code.java.dataflow.DataFlow3
9
7
import semmle.code.java.dataflow.FlowSources
10
8
11
9
/** A method call that produces cryptographic result. */
@@ -51,25 +49,25 @@ private class ProduceSignatureCall extends ProduceCryptoCall {
51
49
* A config that tracks data flow from initializing a cipher for encryption
52
50
* to producing a ciphertext using this cipher.
53
51
*/
54
- private class InitializeEncryptorConfig extends DataFlow3:: Configuration {
55
- InitializeEncryptorConfig ( ) { this = "InitializeEncryptorConfig" }
56
-
57
- override predicate isSource ( DataFlow:: Node source ) {
52
+ private module InitializeEncryptorConfig implements DataFlow:: ConfigSig {
53
+ predicate isSource ( DataFlow:: Node source ) {
58
54
exists ( MethodAccess ma |
59
55
ma .getMethod ( ) .hasQualifiedName ( "javax.crypto" , "Cipher" , "init" ) and
60
56
ma .getArgument ( 0 ) .( VarAccess ) .getVariable ( ) .hasName ( "ENCRYPT_MODE" ) and
61
57
ma .getQualifier ( ) = source .asExpr ( )
62
58
)
63
59
}
64
60
65
- override predicate isSink ( DataFlow:: Node sink ) {
61
+ predicate isSink ( DataFlow:: Node sink ) {
66
62
exists ( MethodAccess ma |
67
63
ma .getMethod ( ) .hasQualifiedName ( "javax.crypto" , "Cipher" , "doFinal" ) and
68
64
ma .getQualifier ( ) = sink .asExpr ( )
69
65
)
70
66
}
71
67
}
72
68
69
+ private module InitializeEncryptorFlow = DataFlow:: Global< InitializeEncryptorConfig > ;
70
+
73
71
/** A method call that produces a ciphertext. */
74
72
private class ProduceCiphertextCall extends ProduceCryptoCall {
75
73
ProduceCiphertextCall ( ) {
@@ -90,9 +88,7 @@ private class ProduceCiphertextCall extends ProduceCryptoCall {
90
88
this .getArgument ( 1 ) = output
91
89
)
92
90
) and
93
- exists ( InitializeEncryptorConfig config |
94
- config .hasFlowTo ( DataFlow3:: exprNode ( this .getQualifier ( ) ) )
95
- )
91
+ InitializeEncryptorFlow:: flowToExpr ( this .getQualifier ( ) )
96
92
}
97
93
98
94
override string getResultType ( ) { result = "ciphertext" }
@@ -151,16 +147,14 @@ private predicate updateMessageDigestStep(DataFlow2::Node fromNode, DataFlow2::N
151
147
* A config that tracks data flow from remote user input to a cryptographic operation
152
148
* such as cipher, MAC or signature.
153
149
*/
154
- private class UserInputInCryptoOperationConfig extends TaintTracking2:: Configuration {
155
- UserInputInCryptoOperationConfig ( ) { this = "UserInputInCryptoOperationConfig" }
156
-
157
- override predicate isSource ( DataFlow:: Node source ) { source instanceof RemoteFlowSource }
150
+ private module UserInputInCryptoOperationConfig implements DataFlow:: ConfigSig {
151
+ predicate isSource ( DataFlow:: Node source ) { source instanceof RemoteFlowSource }
158
152
159
- override predicate isSink ( DataFlow:: Node sink ) {
153
+ predicate isSink ( DataFlow:: Node sink ) {
160
154
exists ( ProduceCryptoCall call | call .getQualifier ( ) = sink .asExpr ( ) )
161
155
}
162
156
163
- override predicate isAdditionalTaintStep ( DataFlow2:: Node fromNode , DataFlow2:: Node toNode ) {
157
+ predicate isAdditionalFlowStep ( DataFlow2:: Node fromNode , DataFlow2:: Node toNode ) {
164
158
updateCryptoOperationStep ( fromNode , toNode )
165
159
or
166
160
createMessageDigestStep ( fromNode , toNode )
@@ -169,6 +163,13 @@ private class UserInputInCryptoOperationConfig extends TaintTracking2::Configura
169
163
}
170
164
}
171
165
166
+ /**
167
+ * Taint-tracking flow from remote user input to a cryptographic operation
168
+ * such as cipher, MAC or signature.
169
+ */
170
+ private module UserInputInCryptoOperationFlow =
171
+ TaintTracking:: Global< UserInputInCryptoOperationConfig > ;
172
+
172
173
/** A source that produces result of cryptographic operation. */
173
174
class CryptoOperationSource extends DataFlow:: Node {
174
175
ProduceCryptoCall call ;
@@ -177,8 +178,8 @@ class CryptoOperationSource extends DataFlow::Node {
177
178
178
179
/** Holds if remote user input was used in the cryptographic operation. */
179
180
predicate includesUserInput ( ) {
180
- exists ( DataFlow2 :: PathNode sink , UserInputInCryptoOperationConfig config |
181
- config . hasFlowPath ( _, sink )
181
+ exists ( UserInputInCryptoOperationFlow :: PathNode sink |
182
+ UserInputInCryptoOperationFlow :: flowPath ( _, sink )
182
183
|
183
184
sink .getNode ( ) .asExpr ( ) = call .getQualifier ( )
184
185
)
@@ -212,12 +213,10 @@ private class NonConstantTimeComparisonCall extends StaticMethodAccess {
212
213
* A config that tracks data flow from remote user input to methods
213
214
* that compare inputs using a non-constant-time algorithm.
214
215
*/
215
- private class UserInputInComparisonConfig extends TaintTracking2 :: Configuration {
216
- UserInputInComparisonConfig ( ) { this = "UserInputInComparisonConfig" }
216
+ private module UserInputInComparisonConfig implements DataFlow :: ConfigSig {
217
+ predicate isSource ( DataFlow :: Node source ) { source instanceof RemoteFlowSource }
217
218
218
- override predicate isSource ( DataFlow:: Node source ) { source instanceof RemoteFlowSource }
219
-
220
- override predicate isSink ( DataFlow:: Node sink ) {
219
+ predicate isSink ( DataFlow:: Node sink ) {
221
220
exists ( NonConstantTimeEqualsCall call |
222
221
sink .asExpr ( ) = [ call .getAnArgument ( ) , call .getQualifier ( ) ]
223
222
)
@@ -226,6 +225,8 @@ private class UserInputInComparisonConfig extends TaintTracking2::Configuration
226
225
}
227
226
}
228
227
228
+ private module UserInputInComparisonFlow = TaintTracking:: Global< UserInputInComparisonConfig > ;
229
+
229
230
/** Holds if `expr` looks like a constant. */
230
231
private predicate looksLikeConstant ( Expr expr ) {
231
232
expr .isCompileTimeConstant ( )
@@ -301,21 +302,18 @@ class NonConstantTimeComparisonSink extends DataFlow::Node {
301
302
}
302
303
303
304
/** Holds if remote user input was used in the comparison. */
304
- predicate includesUserInput ( ) {
305
- exists ( UserInputInComparisonConfig config |
306
- config .hasFlowTo ( DataFlow2:: exprNode ( anotherParameter ) )
307
- )
308
- }
305
+ predicate includesUserInput ( ) { UserInputInComparisonFlow:: flowToExpr ( anotherParameter ) }
309
306
}
310
307
311
308
/**
312
309
* A configuration that tracks data flow from cryptographic operations
313
310
* to methods that compare data using a non-constant-time algorithm.
314
311
*/
315
- class NonConstantTimeCryptoComparisonConfig extends TaintTracking:: Configuration {
316
- NonConstantTimeCryptoComparisonConfig ( ) { this = "NonConstantTimeCryptoComparisonConfig" }
317
-
318
- override predicate isSource ( DataFlow:: Node source ) { source instanceof CryptoOperationSource }
312
+ module NonConstantTimeCryptoComparisonConfig implements DataFlow:: ConfigSig {
313
+ predicate isSource ( DataFlow:: Node source ) { source instanceof CryptoOperationSource }
319
314
320
- override predicate isSink ( DataFlow:: Node sink ) { sink instanceof NonConstantTimeComparisonSink }
315
+ predicate isSink ( DataFlow:: Node sink ) { sink instanceof NonConstantTimeComparisonSink }
321
316
}
317
+
318
+ module NonConstantTimeCryptoComparisonFlow =
319
+ TaintTracking:: Global< NonConstantTimeCryptoComparisonConfig > ;
0 commit comments