add model for the core Digest module

This commit is contained in:
erik-krogh
2022-10-14 11:25:05 +02:00
parent 7c912ea876
commit e2476949b9
4 changed files with 63 additions and 0 deletions

View File

@@ -14,6 +14,7 @@ import core.Hash
import core.String
import core.Regexp
import core.IO
import core.Digest
/**
* A system command executed via subshell literal syntax.

View File

@@ -0,0 +1,34 @@
/**
* Provides modeling for the `Digest` module.
*/
private import codeql.ruby.ApiGraphs
private import codeql.ruby.Concepts
private import codeql.ruby.DataFlow
/** Gets an API node for a Digest class that hashes using `algo`. */
private API::Node digest(Cryptography::HashingAlgorithm algo) {
exists(string name | result = API::getTopLevelMember("Digest").getMember(name) |
name = ["MD5", "SHA1", "SHA2", "RMD160"] and
algo.matchesName(name)
)
}
/** A call that hashes some input using a hashing algorithm from the `Digest` module. */
private class DigestCall extends Cryptography::CryptographicOperation::Range instanceof DataFlow::CallNode {
Cryptography::HashingAlgorithm algo;
DigestCall() {
this = digest(algo).getAMethodCall(["hexdigest", "base64digest", "bubblebabble"])
or
this = digest(algo).getAMethodCall("file") // it's directly hashing the contents of a file, but that's close enough for us.
or
this = digest(algo).getMethod("new").getReturn().getAMethodCall(["digest", "update", "<<"])
}
override Cryptography::HashingAlgorithm getAlgorithm() { result = algo }
override DataFlow::Node getAnInput() { result = super.getArgument(0) }
override Cryptography::BlockMode getBlockMode() { none() }
}

View File

@@ -17,3 +17,10 @@
| broken_crypto.rb:75:1:75:24 | call to new | The cryptographic algorithm RC4 is broken or weak, and should not be used. |
| broken_crypto.rb:77:1:77:29 | call to new | The cryptographic algorithm RC4 is broken or weak, and should not be used. |
| broken_crypto.rb:79:1:79:35 | call to new | The cryptographic algorithm RC4 is broken or weak, and should not be used. |
| broken_crypto.rb:81:1:81:28 | call to hexdigest | The cryptographic algorithm MD5 is broken or weak, and should not be used. |
| broken_crypto.rb:84:1:84:31 | call to base64digest | The cryptographic algorithm MD5 is broken or weak, and should not be used. |
| broken_crypto.rb:87:1:87:20 | call to digest | The cryptographic algorithm MD5 is broken or weak, and should not be used. |
| broken_crypto.rb:89:1:89:21 | call to update | The cryptographic algorithm MD5 is broken or weak, and should not be used. |
| 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. |

View File

@@ -77,3 +77,24 @@ OpenSSL::Cipher::RC4.new
OpenSSL::Cipher::RC4.new '40'
# BAD: weak encryption algorithm
OpenSSL::Cipher::RC4.new 'hmac-md5'
Digest::MD5.hexdigest('foo') # BAD: weak hash algorithm
Digest::SHA256.hexdigest('foo') # GOOD: strong hash algorithm
Digest::MD5.base64digest('foo') # BAD: weak hash algorithm
md5 = Digest::MD5.new
md5.digest 'message' # BAD: weak hash algorithm
md5.update 'message1' # BAD: weak hash algorithm
md5 << 'message2' # << is an alias for update
sha256 = Digest::SHA256.new
sha256.digest 'message' # GOOD: strong hash algorithm
Digest::MD5.bubblebabble 'message' # BAD: weak hash algorithm
filemd5 = Digest::MD5.file 'testfile'
filemd5.hexdigest
Digest("MD5").hexdigest('foo') # BAD: weak hash algorithm