Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 40d3f22

Browse files
author
dilanbhalla
committed
fixing commit error
1 parent 37eca95 commit 40d3f22

File tree

11 files changed

+342
-78
lines changed

11 files changed

+342
-78
lines changed

ql/src/experimental/CWE-327/BrokenCrypto.ql

Lines changed: 0 additions & 15 deletions
This file was deleted.

ql/src/experimental/CWE-327/CryptoLibraries.qll

Lines changed: 130 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,84 @@ import go
66

77
/**
88
* Names of cryptographic algorithms, separated into strong and weak variants.
9+
*
910
* The names are normalized: upper-case, no spaces, dashes or underscores.
11+
*
1012
* The names are inspired by the names used in real world crypto libraries.
11-
* The classification into strong and weak are based on Wikipedia, OWASP and google (2017).
13+
*
14+
* The classification into strong and weak are based on OWASP and Wikipedia (2020).
15+
*
16+
* Sources (more links in qhelp file):
17+
* https://en.wikipedia.org/wiki/Strong_cryptography#Cryptographically_strong_algorithms
18+
* https://en.wikipedia.org/wiki/Strong_cryptography#Examples
19+
* https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html
1220
*/
1321
private module AlgorithmNames {
22+
predicate isStrongHashingAlgorithm(string name) {
23+
name = "DSA" or
24+
name = "ED25519" or
25+
name = "ES256" or
26+
name = "ECDSA256" or
27+
name = "ES384" or
28+
name = "ECDSA384" or
29+
name = "ES512" or
30+
name = "ECDSA512" or
31+
name = "SHA2" or
32+
name = "SHA224" or
33+
name = "SHA256" or
34+
name = "SHA384" or
35+
name = "SHA512" or
36+
name = "SHA3"
37+
}
38+
1439
predicate isWeakHashingAlgorithm(string name) {
40+
name = "HAVEL128" or
41+
name = "MD2" or
42+
name = "MD4" or
1543
name = "MD5" or
44+
name = "PANAMA" or
45+
name = "RIPEMD" or
46+
name = "RIPEMD128" or
47+
name = "RIPEMD256" or
48+
name = "RIPEMD320" or
49+
name = "SHA0" or
1650
name = "SHA1"
1751
}
1852

53+
predicate isStrongEncryptionAlgorithm(string name) {
54+
name = "AES" or
55+
name = "AES128" or
56+
name = "AES192" or
57+
name = "AES256" or
58+
name = "AES512" or
59+
name = "RSA" or
60+
name = "RABBIT" or
61+
name = "BLOWFISH"
62+
}
63+
1964
predicate isWeakEncryptionAlgorithm(string name) {
2065
name = "DES" or
21-
name = "RC4"
66+
name = "3DES" or
67+
name = "TRIPLEDES" or
68+
name = "TDEA" or
69+
name = "TRIPLEDEA" or
70+
name = "ARC2" or
71+
name = "RC2" or
72+
name = "ARC4" or
73+
name = "RC4" or
74+
name = "ARCFOUR" or
75+
name = "ARC5" or
76+
name = "RC5"
2277
}
78+
79+
predicate isStrongPasswordHashingAlgorithm(string name) {
80+
name = "ARGON2" or
81+
name = "PBKDF2" or
82+
name = "BCRYPT" or
83+
name = "SCRYPT"
84+
}
85+
86+
predicate isWeakPasswordHashingAlgorithm(string name) { none() }
2387
}
2488

2589
private import AlgorithmNames
@@ -28,9 +92,20 @@ private import AlgorithmNames
2892
* A cryptographic algorithm.
2993
*/
3094
private newtype TCryptographicAlgorithm =
31-
MkHashingAlgorithm(string name, boolean isWeak) { isWeakHashingAlgorithm(name) and isWeak = true } or
95+
MkHashingAlgorithm(string name, boolean isWeak) {
96+
isStrongHashingAlgorithm(name) and isWeak = false
97+
or
98+
isWeakHashingAlgorithm(name) and isWeak = true
99+
} or
32100
MkEncryptionAlgorithm(string name, boolean isWeak) {
101+
isStrongEncryptionAlgorithm(name) and isWeak = false
102+
or
33103
isWeakEncryptionAlgorithm(name) and isWeak = true
104+
} or
105+
MkPasswordHashingAlgorithm(string name, boolean isWeak) {
106+
isStrongPasswordHashingAlgorithm(name) and isWeak = false
107+
or
108+
isWeakPasswordHashingAlgorithm(name) and isWeak = true
34109
}
35110

36111
/**
@@ -46,11 +121,13 @@ abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
46121
abstract string getName();
47122

48123
/**
49-
* Holds if the name of this algorithm matches `name` modulo case, white space, dashes and underscores.
124+
* Holds if the name of this algorithm matches `name` modulo case,
125+
* white space, dashes and underscores.
50126
*/
51127
bindingset[name]
52128
predicate matchesName(string name) {
53129
exists(name.regexpReplaceAll("[-_]", "").regexpFind("(?i)\\Q" + getName() + "\\E", _, _))
130+
// name.toUpperCase().regexpReplaceAll("[-_ ]", "").regexpMatch(".*" + getName() + ".*")
54131
}
55132

56133
/**
@@ -60,7 +137,7 @@ abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
60137
}
61138

62139
/**
63-
* A hashing algorithm
140+
* A hashing algorithm such as `MD5` or `SHA512`.
64141
*/
65142
class HashingAlgorithm extends MkHashingAlgorithm, CryptographicAlgorithm {
66143
string name;
@@ -74,7 +151,7 @@ class HashingAlgorithm extends MkHashingAlgorithm, CryptographicAlgorithm {
74151
}
75152

76153
/**
77-
* An encryption algorithm
154+
* An encryption algorithm such as `DES` or `AES512`.
78155
*/
79156
class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm {
80157
string name;
@@ -87,97 +164,100 @@ class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm
87164
override predicate isWeak() { isWeak = true }
88165
}
89166

167+
/**
168+
* A password hashing algorithm such as `PBKDF2` or `SCRYPT`.
169+
*/
170+
class PasswordHashingAlgorithm extends MkPasswordHashingAlgorithm, CryptographicAlgorithm {
171+
string name;
172+
boolean isWeak;
173+
174+
PasswordHashingAlgorithm() { this = MkPasswordHashingAlgorithm(name, isWeak) }
175+
176+
override string getName() { result = name }
177+
178+
override predicate isWeak() { isWeak = true }
179+
}
180+
90181
/**
91182
* An application of a cryptographic algorithm.
92183
*/
93-
abstract class CryptographicOperation extends Expr {
184+
abstract class CryptographicOperation extends DataFlow::Node {
185+
/**
186+
* Gets the input the algorithm is used on, e.g. the plain text input to be encrypted.
187+
*/
188+
abstract Expr getInput();
189+
94190
/**
95191
* Gets the applied algorithm.
96192
*/
97193
abstract CryptographicAlgorithm getAlgorithm();
98194
}
99195

100196
/**
197+
* Below are the cryptographic functions that have been implemented so far for this library.
101198
* Class that checks for use of Md5 package.
102199
*/
103-
class Md5 extends CryptographicOperation {
200+
class Md5 extends CryptographicOperation, DataFlow::CallNode {
201+
Expr input;
104202
CryptographicAlgorithm algorithm;
105-
SelectorExpr sel;
106-
CallExpr call;
107203

108204
Md5() {
109-
this = call and
110-
algorithm.matchesName(sel.getBase().toString()) and
111-
algorithm.matchesName("MD5") and
112-
sel.getSelector().toString() = call.getCalleeName().toString() and
113-
(
114-
call.getCalleeName().toString() = "New" or
115-
call.getCalleeName().toString() = "Sum"
116-
)
205+
getTarget().hasQualifiedName("crypto/md5", ["New", "Sum"]) and
206+
this.getArgument(0).asExpr() = input
117207
}
118208

209+
override Expr getInput() { result = input }
210+
119211
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
120212
}
121213

122214
/**
123-
* Class that checks for use of SHA1 package.
215+
* Class that checks for use of Sha1 package.
124216
*/
125-
class Sha1 extends CryptographicOperation {
217+
class Sha1 extends CryptographicOperation, DataFlow::CallNode {
218+
Expr input;
126219
CryptographicAlgorithm algorithm;
127-
SelectorExpr sel;
128-
CallExpr call;
129220

130221
Sha1() {
131-
this = call and
132-
algorithm.matchesName(sel.getBase().toString()) and
133-
algorithm.matchesName("SHA1") and
134-
sel.getSelector().toString() = call.getCalleeName().toString() and
135-
(
136-
call.getCalleeName().toString() = "New" or
137-
call.getCalleeName().toString() = "Sum"
138-
)
222+
getTarget().hasQualifiedName("crypto/sha1", ["New", "Sum"]) and
223+
this.getArgument(0).asExpr() = input
139224
}
140225

226+
override Expr getInput() { result = input }
227+
141228
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
142229
}
143230

144231
/**
145232
* Class that checks for use of Des package.
146233
*/
147-
class Des extends CryptographicOperation {
234+
class Des extends CryptographicOperation, DataFlow::CallNode {
235+
Expr input;
148236
CryptographicAlgorithm algorithm;
149-
SelectorExpr sel;
150-
CallExpr call;
151237

152238
Des() {
153-
this = call and
154-
algorithm.matchesName(sel.getBase().toString()) and
155-
algorithm.matchesName("DES") and
156-
sel.getSelector().toString() = call.getCalleeName().toString() and
157-
(
158-
call.getCalleeName().toString() = "NewCipher" or
159-
call.getCalleeName().toString() = "NewTripleDESCipher"
160-
)
239+
getTarget().hasQualifiedName("crypto/des", ["NewCipher", "NewTripleDESCipher"]) and
240+
this.getArgument(0).asExpr() = input
161241
}
162242

243+
override Expr getInput() { result = input }
244+
163245
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
164246
}
165247

166248
/**
167-
* Class that checks for use of RC4 package.
249+
* Class that checks for use of Rc4 package.
168250
*/
169-
class Rc4 extends CryptographicOperation {
251+
class Rc4 extends CryptographicOperation, DataFlow::CallNode {
252+
Expr input;
170253
CryptographicAlgorithm algorithm;
171-
SelectorExpr sel;
172-
CallExpr call;
173254

174255
Rc4() {
175-
this = call and
176-
algorithm.matchesName(sel.getBase().toString()) and
177-
algorithm.matchesName("RC4") and
178-
sel.getSelector().toString() = call.getCalleeName().toString() and
179-
call.getCalleeName().toString() = "NewCipher"
256+
getTarget().hasQualifiedName("crypto/rc4", ["NewCipher"]) and
257+
this.getArgument(0).asExpr() = input
180258
}
181259

260+
override Expr getInput() { result = input }
261+
182262
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
183263
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>
7+
Using weak cryptographic algorithms can leave data
8+
vulnerable to being decrypted or forged by an attacker.
9+
</p>
10+
11+
<p>
12+
Many cryptographic algorithms provided by cryptography
13+
libraries are known to be weak. Using such an
14+
algorithm means that encrypted or hashed data is less
15+
secure than it appears to be.
16+
</p>
17+
18+
</overview>
19+
<recommendation>
20+
21+
<p>
22+
Ensure that you use a strong, modern cryptographic
23+
algorithm. Use at least AES-128 or RSA-2048 for
24+
encryption, and SHA-2 or SHA-3 for secure hashing.
25+
</p>
26+
27+
</recommendation>
28+
<example>
29+
30+
<p>
31+
The following code uses the different packages to encrypt/hash
32+
some secret data. The first few examples uses DES, MD5, RC4, and SHA1,
33+
which are older algorithms that are now considered weak. The following
34+
examples use AES and SHA256, which are stronger, more modern algorithms.
35+
</p>
36+
37+
<sample src="examples/Crypto.go" />
38+
39+
</example>
40+
41+
<references>
42+
<li>OWASP: <a
43+
href="https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html">Cryptographic Storage Cheat Sheet</a>.
44+
</li>
45+
<li>Wikipedia: <a
46+
href="https://en.wikipedia.org/wiki/Strong_cryptography#Cryptographically_strong_algorithms">Cryptographically Strong Algorithms</a>.
47+
</li>
48+
<li>Wikipedia: <a
49+
href="https://en.wikipedia.org/wiki/Strong_cryptography#Examples">Strong Cryptography Examples</a>.
50+
</li>
51+
<li>NIST, FIPS 140 Annex a: <a href="http://csrc.nist.gov/publications/fips/fips140-2/fips1402annexa.pdf"> Approved Security Functions</a>.</li>
52+
<li>NIST, SP 800-131A: <a href="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf"> Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths</a>.</li>
53+
</references>
54+
55+
</qhelp>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* @name Use of a weak cryptographic algorithm
3+
* @description Using weak cryptographic algorithms can allow an attacker to compromise security.
4+
* @kind path-problem
5+
* @problem.severity error
6+
* @id go/weak-crypto-algorithm
7+
* @tags security
8+
*/
9+
10+
import go
11+
import WeakCryptoAlgorithmCustomizations::WeakCryptoAlgorithm
12+
import DataFlow::PathGraph
13+
14+
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
15+
where cfg.hasFlowPath(source, sink)
16+
select sink.getNode(), source, sink, "Sensitive data is used in a weak cryptographic algorithm."

0 commit comments

Comments
 (0)