-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathEncryption.qll
More file actions
86 lines (78 loc) · 3.15 KB
/
Encryption.qll
File metadata and controls
86 lines (78 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/**
* Provides predicates relating to encryption in C and C++.
*/
import cpp
/**
* Gets the name of an algorithm that is known to be insecure.
*/
string getAnInsecureAlgorithmName() {
result =
[
"DES", "RC2", "RC4", "RC5", "ARCFOUR", // ARCFOUR is a variant of RC4
"3DES", "DES3" // also appears separated, e.g. "TRIPLE-DES", which will be matched as "DES".
]
}
/**
* Gets the name of an algorithm that is known to be secure.
*/
string getASecureAlgorithmName() {
result = ["RSA", "SHA256", "CCM", "GCM", "AES", "Blowfish", "ECIES"]
}
/**
* Gets the name of a hash algorithm that is insecure if it is being used for
* encryption (but it is hard to know when that is happening).
*/
string getAnInsecureHashAlgorithmName() { result = ["SHA1", "MD5"] }
/**
* Gets the regular expression used for matching strings that look like they
* contain an algorithm that is known to be insecure.
*
* Consider using `isInsecureEncryption` rather than accessing this regular
* expression directly.
*/
string getInsecureAlgorithmRegex() {
result =
// algorithms usually appear in names surrounded by characters that are not
// alphabetical characters in the same case or numerical digits. This
// handles the upper case:
"(^|.*[^A-Z0-9])(" + strictconcat(getAnInsecureAlgorithmName(), "|") + ")([^A-Z0-9].*|$)" + "|" +
// for lowercase, we want to be careful to avoid being confused by
//camelCase, hence we require two preceding uppercase letters to be
// sure of a case switch (or a preceding non-alphabetic, non-numeric
// character).
"(^|.*[A-Z]{2}|.*[^a-zA-Z0-9])(" +
strictconcat(getAnInsecureAlgorithmName().toLowerCase(), "|") + ")([^a-z0-9].*|$)"
}
/**
* Holds if `name` looks like it might be related to operations with an
* insecure encryption algorithm.
*/
bindingset[name]
predicate isInsecureEncryption(string name) { name.regexpMatch(getInsecureAlgorithmRegex()) }
/**
* Holds if there is additional evidence that `name` looks like it might be
* related to operations with an encryption algorithm, besides the name of a
* specific algorithm. This can be used in conjunction with
* `isInsecureEncryption` to produce a stronger heuristic.
*/
bindingset[name]
predicate isEncryptionAdditionalEvidence(string name) {
name.regexpMatch("(?i).*(crypt|code|coding|cbc|key|cipher|mac).*")
}
/**
* Gets a regular expression for matching strings that look like they
* contain an algorithm that is known to be secure.
*/
string getSecureAlgorithmRegex() {
result =
// algorithms usually appear in names surrounded by characters that are not
// alphabetical characters in the same case or numerical digits. This
// handles the upper case:
"(^|.*[^A-Z0-9])(" + strictconcat(getASecureAlgorithmName(), "|") + ")([^A-Z0-9].*|$)" + "|" +
// for lowercase, we want to be careful to avoid being confused by
//camelCase, hence we require two preceding uppercase letters to be
// sure of a case switch (or a preceding non-alphabetic, non-numeric
// character).
"(^|.*[A-Z]{2}|.*[^a-zA-Z0-9])(" + strictconcat(getASecureAlgorithmName().toLowerCase(), "|") +
")([^a-z0-9].*|$)"
}