add model for the core OpenSSL::Digest module

This commit is contained in:
erik-krogh 2022-10-14 13:25:34 +02:00
Родитель e2476949b9
Коммит 7c76645157
Не найден ключ, соответствующий данной подписи
4 изменённых файлов: 58 добавлений и 2 удалений

Просмотреть файл

@ -203,7 +203,7 @@ module API {
/**
* Gets a node representing a call to `method` on the receiver represented by this node.
*/
Node getMethod(string method) {
MethodAccessNode getMethod(string method) {
result = this.getASubclass().getASuccessor(Label::method(method))
}

Просмотреть файл

@ -581,3 +581,49 @@ private class CipherOperation extends Cryptography::CryptographicOperation::Rang
result = cipherNode.getCipherMode().getBlockMode()
}
}
/** Predicates and classes modelling the `OpenSSL::Digest` module */
private module Digest {
private import codeql.ruby.ApiGraphs
/** A call that hashes some input using a hashing algorithm from the `OpenSSL::Digest` module. */
private class DigestCall extends Cryptography::CryptographicOperation::Range instanceof DataFlow::CallNode {
Cryptography::HashingAlgorithm algo;
DigestCall() {
exists(API::MethodAccessNode call |
call = API::getTopLevelMember("OpenSSL").getMember("Digest").getMethod("new")
|
this = call.getReturn().getAMethodCall(["digest", "update", "<<"]) and
algo.matchesName(call.getCallNode()
.getArgument(0)
.asExpr()
.getExpr()
.getConstantValue()
.getString())
)
}
override Cryptography::HashingAlgorithm getAlgorithm() { result = algo }
override DataFlow::Node getAnInput() { result = super.getArgument(0) }
override Cryptography::BlockMode getBlockMode() { none() }
}
/** A call to `OpenSSL::Digest.digest` that hashes input directly without constructing a digest instance. */
private class DigestCallDirect extends Cryptography::CryptographicOperation::Range instanceof DataFlow::CallNode {
Cryptography::HashingAlgorithm algo;
DigestCallDirect() {
this = API::getTopLevelMember("OpenSSL").getMember("Digest").getMethod("digest").getCallNode() and
algo.matchesName(this.getArgument(0).asExpr().getExpr().getConstantValue().getString())
}
override Cryptography::HashingAlgorithm getAlgorithm() { result = algo }
override DataFlow::Node getAnInput() { result = super.getArgument(1) }
override Cryptography::BlockMode getBlockMode() { none() }
}
}

Просмотреть файл

@ -24,3 +24,6 @@
| broken_crypto.rb:90:1:90:17 | ... << ... | The cryptographic algorithm MD5 is broken or weak, and should not be used. |
| broken_crypto.rb:95:1:95:34 | call to bubblebabble | The cryptographic algorithm MD5 is broken or weak, and should not be used. |
| broken_crypto.rb:97:11:97:37 | call to file | The cryptographic algorithm MD5 is broken or weak, and should not be used. |
| broken_crypto.rb:103:1:103:21 | call to digest | The cryptographic algorithm SHA1 is broken or weak, and should not be used. |
| broken_crypto.rb:104:1:104:17 | ... << ... | The cryptographic algorithm SHA1 is broken or weak, and should not be used. |
| broken_crypto.rb:106:1:106:37 | call to digest | The cryptographic algorithm SHA1 is broken or weak, and should not be used. |

Просмотреть файл

@ -97,4 +97,11 @@ Digest::MD5.bubblebabble 'message' # BAD: weak hash algorithm
filemd5 = Digest::MD5.file 'testfile'
filemd5.hexdigest
Digest("MD5").hexdigest('foo') # BAD: weak hash algorithm
Digest("MD5").hexdigest('foo') # BAD: weak hash algorithm
sha1 = OpenSSL::Digest.new('SHA1')
sha1.digest 'message' # BAD: weak hash algorithm
sha1 << 'message' # << is an alias for update
OpenSSL::Digest.digest('SHA1', "abc") # BAD: weak hash algorithm
OpenSSL::Digest.digest('SHA3-512', "abc") # GOOD: strong hash algorithm