Skip to content

Commit efcf7ea

Browse files
committed
Add broken crypto query
1 parent 86e51da commit efcf7ea

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

java/ql/lib/experimental/Quantum/JCA.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ abstract class CipherAlgorithmMode extends Crypto::NodeBase {
126126
result = alg and name = alg.toString()
127127
}
128128

129-
override string getAlgorithmName(){ result = this.getAlgorithmName()}
129+
override string getAlgorithmName(){ result = alg.getValue()}
130130
}
131131

132132

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* @name Use of a broken or risky cryptographic algorithm
3+
* @description Using broken or weak cryptographic algorithms can allow an attacker to compromise security.
4+
* @kind problem
5+
* @problem.severity warning
6+
* @security-severity 7.5
7+
* @precision high
8+
* @id java/weak-cryptographic-algorithm-new-model
9+
* @tags security
10+
* external/cwe/cwe-327
11+
* external/cwe/cwe-328
12+
*/
13+
14+
15+
16+
//THIS QUERY IS A REPLICA OF: https://github.com/github/codeql/blob/main/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql
17+
//but uses the **NEW MODELLING**
18+
import experimental.Quantum.Language
19+
20+
21+
/**
22+
* Gets the name of an algorithm that is known to be insecure.
23+
*/
24+
string getAnInsecureAlgorithmName() {
25+
result =
26+
[
27+
"DES", "RC2", "RC4", "RC5",
28+
// ARCFOUR is a variant of RC4
29+
"ARCFOUR",
30+
// Encryption mode ECB like AES/ECB/NoPadding is vulnerable to replay and other attacks
31+
"ECB",
32+
// CBC mode of operation with PKCS#5 or PKCS#7 padding is vulnerable to padding oracle attacks
33+
"AES/CBC/PKCS[57]Padding"
34+
]
35+
}
36+
37+
private string rankedInsecureAlgorithm(int i) {
38+
result = rank[i](string s | s = getAnInsecureAlgorithmName())
39+
}
40+
41+
private string insecureAlgorithmString(int i) {
42+
i = 1 and result = rankedInsecureAlgorithm(i)
43+
or
44+
result = rankedInsecureAlgorithm(i) + "|" + insecureAlgorithmString(i - 1)
45+
}
46+
47+
/**
48+
* Gets the regular expression used for matching strings that look like they
49+
* contain an algorithm that is known to be insecure.
50+
*/
51+
string getInsecureAlgorithmRegex() {
52+
result = algorithmRegex(insecureAlgorithmString(max(int i | exists(rankedInsecureAlgorithm(i)))))
53+
}
54+
55+
bindingset[algorithmString]
56+
private string algorithmRegex(string algorithmString) {
57+
// Algorithms usually appear in names surrounded by characters that are not
58+
// alphabetical characters in the same case. This handles the upper and lower
59+
// case cases.
60+
result =
61+
"((^|.*[^A-Z])(" + algorithmString + ")([^A-Z].*|$))" +
62+
// or...
63+
"|" +
64+
// For lowercase, we want to be careful to avoid being confused by camelCase
65+
// hence we require two preceding uppercase letters to be sure of a case switch,
66+
// or a preceding non-alphabetic character
67+
"((^|.*[A-Z]{2}|.*[^a-zA-Z])(" + algorithmString.toLowerCase() + ")([^a-z].*|$))"
68+
}
69+
70+
from Crypto::Algorithm alg
71+
where alg.getAlgorithmName().regexpMatch(getInsecureAlgorithmRegex()) and
72+
// Exclude RSA/ECB/.* ciphers.
73+
not alg.getAlgorithmName().regexpMatch("RSA/ECB.*") and
74+
// Exclude German and French sentences.
75+
not alg.getAlgorithmName().regexpMatch(".*\\p{IsLowercase} des \\p{IsLetter}.*")
76+
select alg, "Cryptographic algorithm $@ is weak and should not be used.", alg,
77+
alg.getAlgorithmName()

0 commit comments

Comments
 (0)