1
1
/**
2
2
* @name Using a non-constant time algorithm for comparing results of a cryptographic operation
3
3
* @description When comparing results of a cryptographic operation, a constant time algorithm should be used.
4
- * Otherwise, an attacker may be able to implement a timing attack.
4
+ * Otherwise, attackers may be able to implement a timing attack if they can control input .
5
5
* A successful attack may result in leaking secrets or authentication bypass.
6
6
* @kind path-problem
7
7
* @problem.severity warning
@@ -21,12 +21,15 @@ private class ByteBuffer extends Class {
21
21
ByteBuffer ( ) { hasQualifiedName ( "java.nio" , "ByteBuffer" ) }
22
22
}
23
23
24
+ /** A method call that produces cryptographic result. */
24
25
abstract private class ProduceCryptoCall extends MethodAccess {
25
26
Expr output ;
26
27
28
+ /** Return the result of cryptographic operation. */
27
29
Expr output ( ) { result = output }
28
30
}
29
31
32
+ /** A method call that produces a MAC. */
30
33
private class ProduceMacCall extends ProduceCryptoCall {
31
34
ProduceMacCall ( ) {
32
35
getMethod ( ) .hasQualifiedName ( "javax.crypto" , "Mac" , "doFinal" ) and
@@ -38,6 +41,7 @@ private class ProduceMacCall extends ProduceCryptoCall {
38
41
}
39
42
}
40
43
44
+ /** A method call that produces a signature. */
41
45
private class ProduceSignatureCall extends ProduceCryptoCall {
42
46
ProduceSignatureCall ( ) {
43
47
getMethod ( ) .hasQualifiedName ( "java.security" , "Signature" , "sign" ) and
@@ -49,6 +53,7 @@ private class ProduceSignatureCall extends ProduceCryptoCall {
49
53
}
50
54
}
51
55
56
+ /** A method call that produces a ciphertext. */
52
57
private class ProduceCiphertextCall extends ProduceCryptoCall {
53
58
ProduceCiphertextCall ( ) {
54
59
getMethod ( ) .hasQualifiedName ( "javax.crypto" , "Cipher" , "doFinal" ) and
@@ -63,6 +68,10 @@ private class ProduceCiphertextCall extends ProduceCryptoCall {
63
68
}
64
69
}
65
70
71
+ /**
72
+ * A config that tracks data flow from remote user input to a cryptographic operation
73
+ * such as cipher, MAC or signature.
74
+ */
66
75
private class UserInputInCryptoOperationConfig extends TaintTracking2:: Configuration {
67
76
UserInputInCryptoOperationConfig ( ) { this = "UserInputInCryptoOperationConfig" }
68
77
@@ -72,6 +81,7 @@ private class UserInputInCryptoOperationConfig extends TaintTracking2::Configura
72
81
exists ( ProduceCryptoCall call | call .getQualifier ( ) = sink .asExpr ( ) )
73
82
}
74
83
84
+ /** Holds if `fromNode` to `toNode` is a dataflow step that updates a cryptographic operation. */
75
85
override predicate isAdditionalTaintStep ( DataFlow2:: Node fromNode , DataFlow2:: Node toNode ) {
76
86
exists ( MethodAccess call , Method m |
77
87
m = call .getMethod ( ) and
@@ -90,6 +100,7 @@ private class UserInputInCryptoOperationConfig extends TaintTracking2::Configura
90
100
}
91
101
}
92
102
103
+ /** A source that produces result of cryptographic operation. */
93
104
private class CryptoOperationSource extends DataFlow:: Node {
94
105
Expr cryptoOperation ;
95
106
@@ -99,6 +110,7 @@ private class CryptoOperationSource extends DataFlow::Node {
99
110
)
100
111
}
101
112
113
+ /** Holds if remote user input was used in the cryptographic operation. */
102
114
predicate includesUserInput ( ) {
103
115
exists (
104
116
DataFlow2:: PathNode source , DataFlow2:: PathNode sink , UserInputInCryptoOperationConfig config
@@ -128,6 +140,10 @@ private class NonConstantTimeComparisonCall extends StaticMethodAccess {
128
140
}
129
141
}
130
142
143
+ /**
144
+ * A config that tracks data flow from remote user input to methods
145
+ * that compare inputs using a non-constant time algorithm.
146
+ */
131
147
private class UserInputInComparisonConfig extends TaintTracking2:: Configuration {
132
148
UserInputInComparisonConfig ( ) { this = "UserInputInComparisonConfig" }
133
149
@@ -142,15 +158,14 @@ private class UserInputInComparisonConfig extends TaintTracking2::Configuration
142
158
}
143
159
}
144
160
161
+ /** Holds if `expr` looks like a constant. */
145
162
private predicate looksLikeConstant ( Expr expr ) {
146
163
expr .isCompileTimeConstant ( )
147
164
or
148
165
expr .( VarAccess ) .getVariable ( ) .isFinal ( ) and expr .getType ( ) instanceof TypeString
149
166
}
150
167
151
- /**
152
- * A sink that compares input using a non-constant time algorithm.
153
- */
168
+ /** A sink that compares input using a non-constant time algorithm. */
154
169
private class NonConstantTimeComparisonSink extends DataFlow:: Node {
155
170
Expr anotherParameter ;
156
171
@@ -176,6 +191,7 @@ private class NonConstantTimeComparisonSink extends DataFlow::Node {
176
191
not looksLikeConstant ( anotherParameter )
177
192
}
178
193
194
+ /** Holds if remote user input was used in the comparison. */
179
195
predicate includesUserInput ( ) {
180
196
exists ( UserInputInComparisonConfig config |
181
197
config .hasFlowTo ( DataFlow2:: exprNode ( anotherParameter ) )
0 commit comments