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

Commit 37eca95

Browse files
author
dilanbhalla
committed
restructured library
1 parent 79002b0 commit 37eca95

File tree

9 files changed

+88
-193
lines changed

9 files changed

+88
-193
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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 error
6+
* @id go/broken-crypto
7+
* @tags security
8+
*/
9+
10+
import go
11+
import CryptoLibraries
12+
13+
from CryptographicOperation badcrypto
14+
where badcrypto.getAlgorithm().isWeak()
15+
select badcrypto, "Use of weak or broken cryptographic algorithm"

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

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

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

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

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

Lines changed: 52 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -6,79 +6,20 @@ import go
66

77
/**
88
* Names of cryptographic algorithms, separated into strong and weak variants.
9-
*
109
* The names are normalized: upper-case, no spaces, dashes or underscores.
11-
*
1210
* The names are inspired by the names used in real world crypto libraries.
13-
*
1411
* The classification into strong and weak are based on Wikipedia, OWASP and google (2017).
1512
*/
1613
private module AlgorithmNames {
17-
predicate isStrongHashingAlgorithm(string name) {
18-
name = "DSA" or
19-
name = "ED25519" or
20-
name = "ES256" or
21-
name = "ECDSA256" or
22-
name = "ES384" or
23-
name = "ECDSA384" or
24-
name = "ES512" or
25-
name = "ECDSA512" or
26-
name = "SHA2" or
27-
name = "SHA224" or
28-
name = "SHA256" or
29-
name = "SHA384" or
30-
name = "SHA512" or
31-
name = "SHA3"
32-
}
33-
3414
predicate isWeakHashingAlgorithm(string name) {
35-
name = "HAVEL128" or
36-
name = "MD2" or
37-
name = "MD4" or
3815
name = "MD5" or
39-
name = "PANAMA" or
40-
name = "RIPEMD" or
41-
name = "RIPEMD128" or
42-
name = "RIPEMD256" or
43-
name = "RIPEMD320" or
44-
name = "SHA0" or
4516
name = "SHA1"
4617
}
4718

48-
predicate isStrongEncryptionAlgorithm(string name) {
49-
name = "AES" or
50-
name = "AES128" or
51-
name = "AES192" or
52-
name = "AES256" or
53-
name = "AES512" or
54-
name = "RSA" or
55-
name = "RABBIT" or
56-
name = "BLOWFISH"
57-
}
58-
5919
predicate isWeakEncryptionAlgorithm(string name) {
6020
name = "DES" or
61-
name = "3DES" or
62-
name = "TRIPLEDES" or
63-
name = "TDEA" or
64-
name = "TRIPLEDEA" or
65-
name = "ARC2" or
66-
name = "RC2" or
67-
name = "ARC4" or
68-
name = "RC4" or
69-
name = "ARCFOUR" or
70-
name = "ARC5" or
71-
name = "RC5"
72-
}
73-
74-
predicate isStrongPasswordHashingAlgorithm(string name) {
75-
name = "ARGON2" or
76-
name = "PBKDF2" or
77-
name = "BCRYPT" or
78-
name = "SCRYPT"
21+
name = "RC4"
7922
}
80-
81-
predicate isWeakPasswordHashingAlgorithm(string name) { none() }
8223
}
8324

8425
private import AlgorithmNames
@@ -87,20 +28,9 @@ private import AlgorithmNames
8728
* A cryptographic algorithm.
8829
*/
8930
private newtype TCryptographicAlgorithm =
90-
MkHashingAlgorithm(string name, boolean isWeak) {
91-
isStrongHashingAlgorithm(name) and isWeak = false
92-
or
93-
isWeakHashingAlgorithm(name) and isWeak = true
94-
} or
31+
MkHashingAlgorithm(string name, boolean isWeak) { isWeakHashingAlgorithm(name) and isWeak = true } or
9532
MkEncryptionAlgorithm(string name, boolean isWeak) {
96-
isStrongEncryptionAlgorithm(name) and isWeak = false
97-
or
9833
isWeakEncryptionAlgorithm(name) and isWeak = true
99-
} or
100-
MkPasswordHashingAlgorithm(string name, boolean isWeak) {
101-
isStrongPasswordHashingAlgorithm(name) and isWeak = false
102-
or
103-
isWeakPasswordHashingAlgorithm(name) and isWeak = true
10434
}
10535

10636
/**
@@ -116,13 +46,11 @@ abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
11646
abstract string getName();
11747

11848
/**
119-
* Holds if the name of this algorithm matches `name` modulo case,
120-
* white space, dashes and underscores.
49+
* Holds if the name of this algorithm matches `name` modulo case, white space, dashes and underscores.
12150
*/
12251
bindingset[name]
12352
predicate matchesName(string name) {
12453
exists(name.regexpReplaceAll("[-_]", "").regexpFind("(?i)\\Q" + getName() + "\\E", _, _))
125-
// name.toUpperCase().regexpReplaceAll("[-_ ]", "").regexpMatch(".*" + getName() + ".*")
12654
}
12755

12856
/**
@@ -132,7 +60,7 @@ abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
13260
}
13361

13462
/**
135-
* A hashing algorithm such as `MD5` or `SHA512`.
63+
* A hashing algorithm
13664
*/
13765
class HashingAlgorithm extends MkHashingAlgorithm, CryptographicAlgorithm {
13866
string name;
@@ -146,7 +74,7 @@ class HashingAlgorithm extends MkHashingAlgorithm, CryptographicAlgorithm {
14674
}
14775

14876
/**
149-
* An encryption algorithm such as `DES` or `AES512`.
77+
* An encryption algorithm
15078
*/
15179
class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm {
15280
string name;
@@ -159,41 +87,20 @@ class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm
15987
override predicate isWeak() { isWeak = true }
16088
}
16189

162-
/**
163-
* A password hashing algorithm such as `PBKDF2` or `SCRYPT`.
164-
*/
165-
class PasswordHashingAlgorithm extends MkPasswordHashingAlgorithm, CryptographicAlgorithm {
166-
string name;
167-
boolean isWeak;
168-
169-
PasswordHashingAlgorithm() { this = MkPasswordHashingAlgorithm(name, isWeak) }
170-
171-
override string getName() { result = name }
172-
173-
override predicate isWeak() { isWeak = true }
174-
}
175-
17690
/**
17791
* An application of a cryptographic algorithm.
17892
*/
17993
abstract class CryptographicOperation extends Expr {
180-
/**
181-
* Gets the input the algorithm is used on, e.g. the plain text input to be encrypted.
182-
*/
183-
abstract Expr getInput();
184-
18594
/**
18695
* Gets the applied algorithm.
18796
*/
18897
abstract CryptographicAlgorithm getAlgorithm();
18998
}
19099

191100
/**
192-
* Below are the cryptographic functions that have been implemented so far for this library.
193101
* Class that checks for use of Md5 package.
194102
*/
195103
class Md5 extends CryptographicOperation {
196-
Expr input;
197104
CryptographicAlgorithm algorithm;
198105
SelectorExpr sel;
199106
CallExpr call;
@@ -203,10 +110,33 @@ class Md5 extends CryptographicOperation {
203110
algorithm.matchesName(sel.getBase().toString()) and
204111
algorithm.matchesName("MD5") and
205112
sel.getSelector().toString() = call.getCalleeName().toString() and
206-
call.getArgument(0) = input
113+
(
114+
call.getCalleeName().toString() = "New" or
115+
call.getCalleeName().toString() = "Sum"
116+
)
207117
}
208118

209-
override Expr getInput() { result = input }
119+
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
120+
}
121+
122+
/**
123+
* Class that checks for use of SHA1 package.
124+
*/
125+
class Sha1 extends CryptographicOperation {
126+
CryptographicAlgorithm algorithm;
127+
SelectorExpr sel;
128+
CallExpr call;
129+
130+
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+
)
139+
}
210140

211141
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
212142
}
@@ -215,7 +145,6 @@ class Md5 extends CryptographicOperation {
215145
* Class that checks for use of Des package.
216146
*/
217147
class Des extends CryptographicOperation {
218-
Expr input;
219148
CryptographicAlgorithm algorithm;
220149
SelectorExpr sel;
221150
CallExpr call;
@@ -225,10 +154,30 @@ class Des extends CryptographicOperation {
225154
algorithm.matchesName(sel.getBase().toString()) and
226155
algorithm.matchesName("DES") and
227156
sel.getSelector().toString() = call.getCalleeName().toString() and
228-
call.getArgument(0) = input
157+
(
158+
call.getCalleeName().toString() = "NewCipher" or
159+
call.getCalleeName().toString() = "NewTripleDESCipher"
160+
)
229161
}
230162

231-
override Expr getInput() { result = input }
163+
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
164+
}
165+
166+
/**
167+
* Class that checks for use of RC4 package.
168+
*/
169+
class Rc4 extends CryptographicOperation {
170+
CryptographicAlgorithm algorithm;
171+
SelectorExpr sel;
172+
CallExpr call;
173+
174+
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"
180+
}
232181

233182
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
234183
}

ql/test/experimental/CWE-327/BadCrypto.go

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,29 @@ package main
33
import (
44
"crypto/des"
55
"crypto/md5"
6-
"fmt"
6+
"crypto/rc4"
7+
"crypto/sha1"
8+
"crypto/sha256"
79
)
810

911
func main() {
1012

1113
password := []byte("password")
12-
13-
var tripleDESKey []byte
14-
tripleDESKey = append(tripleDESKey, password[:16]...)
15-
tripleDESKey = append(tripleDESKey, password[:8]...)
16-
1714
// BAD, des is a weak crypto algorithm
18-
_, err := des.NewTripleDESCipher(tripleDESKey)
19-
if err != nil {
20-
panic(err)
21-
}
15+
des.NewTripleDESCipher(password)
2216

2317
// BAD, md5 is a weak crypto algorithm
24-
fmt.Printf("%x", md5.Sum(password))
18+
md5.Sum(password)
19+
20+
key := []byte{ 1, 2, 3, 4, 5, 6, 7 }
21+
// BAD, rc4 is a weak crypto algorithm
22+
rc4.NewCipher(key)
23+
24+
data := []byte("this page intentionally left blank.")
25+
// BAD, sha1 is a weak crypto algorithm
26+
sha1.Sum(data)
2527

28+
sha256key := []byte("hello world")
29+
// GOOD, sha256 is a strong crypto algorithm
30+
sha256.Sum256([]byte(sha256key))
2631
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| BadCrypto.go:15:2:15:33 | call to NewTripleDESCipher | Use of weak or broken cryptographic algorithm |
2+
| BadCrypto.go:18:2:18:18 | call to Sum | Use of weak or broken cryptographic algorithm |
3+
| BadCrypto.go:22:2:22:19 | call to NewCipher | Use of weak or broken cryptographic algorithm |
4+
| BadCrypto.go:26:2:26:15 | call to Sum | Use of weak or broken cryptographic algorithm |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
experimental/CWE-327/BrokenCrypto.ql

ql/test/experimental/CWE-327/BrokenCryptoAlgorithm.expected

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

0 commit comments

Comments
 (0)