Skip to content

Commit 26401fe

Browse files
committed
address PR comments
1 parent 93dd9d0 commit 26401fe

File tree

1 file changed

+35
-52
lines changed

1 file changed

+35
-52
lines changed
Lines changed: 35 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,47 @@
1-
private import codeql.ruby.AST
2-
import codeql.ruby.AST
3-
import codeql.ruby.DataFlow
1+
/**
2+
* @name Unsafe HMAC Comparison
3+
* @description An HMAC is being compared using the equality operator. This may be vulnerable to a cryptographic timing attack
4+
* because the equality operation does not occur in constant time."
5+
6+
* @kind path-problem
7+
* @problem.severity error
8+
* @security-severity 6.0
9+
* @precision high
10+
* @id rb/unsafe-hmac-comparison
11+
* @tags security
12+
* external/cwe/cwe-208
13+
*/
14+
15+
16+
private import codeql.ruby.DataFlow
417
import codeql.ruby.ApiGraphs
5-
import codeql.ruby.dataflow.RemoteFlowSources
6-
import codeql.ruby.TaintTracking
718
import ruby
819

9-
// A call to OpenSSL::HMAC.hexdigest
10-
class OpenSslHmacHexdigest extends DataFlow::Node {
11-
OpenSslHmacHexdigest() {
12-
this = API::getTopLevelMember("OpenSSL").getMember("HMAC").getAMethodCall("hexdigest")
20+
private class OpenSslHmacSource extends DataFlow::Node {
21+
OpenSslHmacSource() {
22+
exists(API::Node hmacNode | hmacNode = API::getTopLevelMember("OpenSSL").getMember("HMAC") |
23+
this = hmacNode.getAMethodCall(["hexdigest", "to_s", "digest", "base64digest"])
24+
or
25+
this = hmacNode.getAnInstantiation()
26+
)
1327
}
1428
}
1529

16-
// A call to OpenSSL::HMAC.to_s (which is an alias for OpenSSL::HMAC.hexdigest)
17-
class OpenSslHmactos extends DataFlow::Node {
18-
OpenSslHmactos() {
19-
this = API::getTopLevelMember("OpenSSL").getMember("HMAC").getAMethodCall("to_s")
20-
}
21-
}
22-
23-
// A call to OpenSSL::HMAC.digest
24-
class OpenSslHmacdigest extends DataFlow::Node {
25-
OpenSslHmacdigest() {
26-
this = API::getTopLevelMember("OpenSSL").getMember("HMAC").getAMethodCall("digest")
27-
}
28-
}
29-
30-
// A call to OpenSSL::HMAC.new
31-
class OpenSslnewHmac extends DataFlow::Node {
32-
OpenSslnewHmac() {
33-
this = API::getTopLevelMember("OpenSSL").getMember("HMAC").getAnInstantiation()
34-
}
35-
}
36-
37-
// A call to OpenSSL::HMAC.base64digest
38-
class OpenSslHmacbase64digest extends DataFlow::Node {
39-
OpenSslHmacbase64digest() {
40-
this = API::getTopLevelMember("OpenSSL").getMember("HMAC").getAMethodCall("base64digest")
41-
}
42-
}
43-
44-
class Configuration extends DataFlow::Configuration {
45-
Configuration() { this = "UnsafeHmacComparison" }
46-
47-
override predicate isSource(DataFlow::Node source) {
48-
source instanceof OpenSslHmacHexdigest or
49-
source instanceof OpenSslnewHmac or
50-
source instanceof OpenSslHmacbase64digest or
51-
source instanceof OpenSslHmacdigest or
52-
source instanceof OpenSslHmactos
53-
}
30+
private module UnsafeHmacComparison {
31+
private module Config implements DataFlow::ConfigSig {
32+
predicate isSource(DataFlow::Node source) {
33+
source instanceof OpenSslHmacSource
34+
}
5435

5536
// Holds if a given sink is an Equality Operation (== or !=)
56-
override predicate isSink(DataFlow::Node sink) {
37+
predicate isSink(DataFlow::Node sink) {
5738
any(EqualityOperation eqOp).getAnOperand() = sink.asExpr().getExpr()
5839
}
40+
}
41+
42+
import DataFlow::Global<Config>
5943
}
6044

61-
from DataFlow::Node source, DataFlow::Node sink, Configuration config
62-
where config.hasFlow(source, sink)
63-
select sink,
64-
"An HMAC is being compared using the equality operator. This may be vulnerable to a cryptographic timing attack because the equality operation does not occur in constant time."
45+
from UnsafeHmacComparison::PathNode source, UnsafeHmacComparison::PathNode sink
46+
where UnsafeHmacComparison::flowPath(source, sink)
47+
select sink.getNode(), source, sink, "This comparison is potentially vulnerable to a timing attack."

0 commit comments

Comments
 (0)