Skip to content

Commit 1b4ee05

Browse files
Better docs for java/non-constant-time-crypto-comparison
1 parent 8c4da16 commit 1b4ee05

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCryptoComparison.qhelp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<p>
66
When comparing results of cryptographic operations, such as MAC or digital signature,
77
a constant time algorithm should be used. In other words, the comparison time should not depend on
8-
the content of the input. Otherwise, an attacker may be able to implement a timing attack.
9-
A successful timing attack may result in leaking secrets or authentication bypass.
8+
the content of the input. Otherwise, attackers may be able to implement a timing attack
9+
if they can control input. A successful timing attack may result in leaking secrets or authentication bypass.
1010
</p>
1111
</overview>
1212

java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCryptoComparison.ql

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @name Using a non-constant time algorithm for comparing results of a cryptographic operation
33
* @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.
55
* A successful attack may result in leaking secrets or authentication bypass.
66
* @kind path-problem
77
* @problem.severity warning
@@ -21,12 +21,15 @@ private class ByteBuffer extends Class {
2121
ByteBuffer() { hasQualifiedName("java.nio", "ByteBuffer") }
2222
}
2323

24+
/** A method call that produces cryptographic result. */
2425
abstract private class ProduceCryptoCall extends MethodAccess {
2526
Expr output;
2627

28+
/** Return the result of cryptographic operation. */
2729
Expr output() { result = output }
2830
}
2931

32+
/** A method call that produces a MAC. */
3033
private class ProduceMacCall extends ProduceCryptoCall {
3134
ProduceMacCall() {
3235
getMethod().hasQualifiedName("javax.crypto", "Mac", "doFinal") and
@@ -38,6 +41,7 @@ private class ProduceMacCall extends ProduceCryptoCall {
3841
}
3942
}
4043

44+
/** A method call that produces a signature. */
4145
private class ProduceSignatureCall extends ProduceCryptoCall {
4246
ProduceSignatureCall() {
4347
getMethod().hasQualifiedName("java.security", "Signature", "sign") and
@@ -49,6 +53,7 @@ private class ProduceSignatureCall extends ProduceCryptoCall {
4953
}
5054
}
5155

56+
/** A method call that produces a ciphertext. */
5257
private class ProduceCiphertextCall extends ProduceCryptoCall {
5358
ProduceCiphertextCall() {
5459
getMethod().hasQualifiedName("javax.crypto", "Cipher", "doFinal") and
@@ -63,6 +68,10 @@ private class ProduceCiphertextCall extends ProduceCryptoCall {
6368
}
6469
}
6570

71+
/**
72+
* A config that tracks data flow from remote user input to a cryptographic operation
73+
* such as cipher, MAC or signature.
74+
*/
6675
private class UserInputInCryptoOperationConfig extends TaintTracking2::Configuration {
6776
UserInputInCryptoOperationConfig() { this = "UserInputInCryptoOperationConfig" }
6877

@@ -72,6 +81,7 @@ private class UserInputInCryptoOperationConfig extends TaintTracking2::Configura
7281
exists(ProduceCryptoCall call | call.getQualifier() = sink.asExpr())
7382
}
7483

84+
/** Holds if `fromNode` to `toNode` is a dataflow step that updates a cryptographic operation. */
7585
override predicate isAdditionalTaintStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) {
7686
exists(MethodAccess call, Method m |
7787
m = call.getMethod() and
@@ -90,6 +100,7 @@ private class UserInputInCryptoOperationConfig extends TaintTracking2::Configura
90100
}
91101
}
92102

103+
/** A source that produces result of cryptographic operation. */
93104
private class CryptoOperationSource extends DataFlow::Node {
94105
Expr cryptoOperation;
95106

@@ -99,6 +110,7 @@ private class CryptoOperationSource extends DataFlow::Node {
99110
)
100111
}
101112

113+
/** Holds if remote user input was used in the cryptographic operation. */
102114
predicate includesUserInput() {
103115
exists(
104116
DataFlow2::PathNode source, DataFlow2::PathNode sink, UserInputInCryptoOperationConfig config
@@ -128,6 +140,10 @@ private class NonConstantTimeComparisonCall extends StaticMethodAccess {
128140
}
129141
}
130142

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+
*/
131147
private class UserInputInComparisonConfig extends TaintTracking2::Configuration {
132148
UserInputInComparisonConfig() { this = "UserInputInComparisonConfig" }
133149

@@ -142,15 +158,14 @@ private class UserInputInComparisonConfig extends TaintTracking2::Configuration
142158
}
143159
}
144160

161+
/** Holds if `expr` looks like a constant. */
145162
private predicate looksLikeConstant(Expr expr) {
146163
expr.isCompileTimeConstant()
147164
or
148165
expr.(VarAccess).getVariable().isFinal() and expr.getType() instanceof TypeString
149166
}
150167

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. */
154169
private class NonConstantTimeComparisonSink extends DataFlow::Node {
155170
Expr anotherParameter;
156171

@@ -176,6 +191,7 @@ private class NonConstantTimeComparisonSink extends DataFlow::Node {
176191
not looksLikeConstant(anotherParameter)
177192
}
178193

194+
/** Holds if remote user input was used in the comparison. */
179195
predicate includesUserInput() {
180196
exists(UserInputInComparisonConfig config |
181197
config.hasFlowTo(DataFlow2::exprNode(anotherParameter))

0 commit comments

Comments
 (0)