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

Commit 95342cd

Browse files
author
dilanbhalla
committed
adding go crypto library
1 parent 097775b commit 95342cd

File tree

6 files changed

+331
-0
lines changed

6 files changed

+331
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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+
* @precision high
7+
* @id go/weak-cryptographic-algorithm
8+
* @tags security
9+
*/
10+
11+
import go
12+
import BrokenCryptoAlgorithmCustomizations::BrokenCryptoAlgorithm
13+
14+
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
15+
where cfg.hasFlowPath(source, sink)
16+
select sink.getNode(), "Sensitive data is used in a broken or weak cryptographic algorithm."
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* Provides default sources, sinks and sanitizers for reasoning about
3+
* sensitive information in broken or weak cryptographic algorithms,
4+
* as well as extension points for adding your own.
5+
*/
6+
7+
import go
8+
private import semmle.go.security.SensitiveActions
9+
private import CryptoLibraries
10+
11+
module BrokenCryptoAlgorithm {
12+
/**
13+
* A data flow source for sensitive information in broken or weak cryptographic algorithms.
14+
*/
15+
abstract class Source extends DataFlow::Node { }
16+
17+
/**
18+
* A data flow sink for sensitive information in broken or weak cryptographic algorithms.
19+
*/
20+
abstract class Sink extends DataFlow::Node { }
21+
22+
/**
23+
* A sanitizer for sensitive information in broken or weak cryptographic algorithms.
24+
*/
25+
abstract class Sanitizer extends DataFlow::Node { }
26+
27+
/**
28+
* A sensitive source.
29+
*/
30+
class SensitiveSource extends Source {
31+
SensitiveSource() { this.asExpr() instanceof SensitiveExpr }
32+
}
33+
34+
/**
35+
* An expression used by a broken or weak cryptographic algorithm.
36+
*/
37+
class WeakCryptographicOperationSink extends Sink {
38+
WeakCryptographicOperationSink() {
39+
exists(CryptographicOperation application |
40+
application.getAlgorithm().isWeak() and
41+
this.asExpr() = application.getInput()
42+
)
43+
}
44+
}
45+
46+
class Configuration extends TaintTracking::Configuration {
47+
Configuration() { this = "BrokenCryptoAlgorithm" }
48+
49+
override predicate isSource(DataFlow::Node source) { source instanceof SensitiveSource }
50+
51+
override predicate isSink(DataFlow::Node sink) {
52+
sink instanceof WeakCryptographicOperationSink
53+
}
54+
55+
override predicate isSanitizer(DataFlow::Node node) {
56+
super.isSanitizer(node) or
57+
node instanceof Sanitizer
58+
}
59+
}
60+
}
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/**
2+
* Provides classes for modelling cryptographic libraries.
3+
*/
4+
5+
import go
6+
7+
/**
8+
* Names of cryptographic algorithms, separated into strong and weak variants.
9+
*
10+
* The names are normalized: upper-case, no spaces, dashes or underscores.
11+
*
12+
* The names are inspired by the names used in real world crypto libraries.
13+
*
14+
* The classification into strong and weak are based on Wikipedia, OWASP and google (2017).
15+
*/
16+
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+
34+
predicate isWeakHashingAlgorithm(string name) {
35+
name = "HAVEL128" or
36+
name = "MD2" or
37+
name = "MD4" or
38+
name = "MD5" or
39+
name = "PANAMA" or
40+
name = "RIPEMD" or
41+
name = "RIPEMD128" or
42+
name = "RIPEMD256" or
43+
name = "RIPEMD160" or
44+
name = "RIPEMD320" or
45+
name = "SHA0" or
46+
name = "SHA1"
47+
}
48+
49+
predicate isStrongEncryptionAlgorithm(string name) {
50+
name = "AES" or
51+
name = "AES128" or
52+
name = "AES192" or
53+
name = "AES256" or
54+
name = "AES512" or
55+
name = "RSA" or
56+
name = "RABBIT" or
57+
name = "BLOWFISH"
58+
}
59+
60+
predicate isWeakEncryptionAlgorithm(string name) {
61+
name = "DES" or
62+
name = "3DES" or
63+
name = "TRIPLEDES" or
64+
name = "TDEA" or
65+
name = "TRIPLEDEA" or
66+
name = "ARC2" or
67+
name = "RC2" or
68+
name = "ARC4" or
69+
name = "RC4" or
70+
name = "ARCFOUR" or
71+
name = "ARC5" or
72+
name = "RC5"
73+
}
74+
75+
predicate isStrongPasswordHashingAlgorithm(string name) {
76+
name = "ARGON2" or
77+
name = "PBKDF2" or
78+
name = "BCRYPT" or
79+
name = "SCRYPT"
80+
}
81+
82+
predicate isWeakPasswordHashingAlgorithm(string name) { none() }
83+
}
84+
85+
private import AlgorithmNames
86+
87+
/**
88+
* A cryptographic algorithm.
89+
*/
90+
private newtype TCryptographicAlgorithm =
91+
MkHashingAlgorithm(string name, boolean isWeak) {
92+
isStrongHashingAlgorithm(name) and isWeak = false
93+
or
94+
isWeakHashingAlgorithm(name) and isWeak = true
95+
} or
96+
MkEncryptionAlgorithm(string name, boolean isWeak) {
97+
isStrongEncryptionAlgorithm(name) and isWeak = false
98+
or
99+
isWeakEncryptionAlgorithm(name) and isWeak = true
100+
} or
101+
MkPasswordHashingAlgorithm(string name, boolean isWeak) {
102+
isStrongPasswordHashingAlgorithm(name) and isWeak = false
103+
or
104+
isWeakPasswordHashingAlgorithm(name) and isWeak = true
105+
}
106+
107+
/**
108+
* A cryptographic algorithm.
109+
*/
110+
abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
111+
/** Gets a textual representation of this element. */
112+
string toString() { result = getName() }
113+
114+
/**
115+
* Gets the name of this algorithm.
116+
*/
117+
abstract string getName();
118+
119+
/**
120+
* Holds if the name of this algorithm matches `name` modulo case,
121+
* white space, dashes and underscores.
122+
*/
123+
bindingset[name]
124+
predicate matchesName(string name) {
125+
name.toUpperCase().regexpReplaceAll("[-_ ]", "").regexpMatch(".*" + getName() + ".*")
126+
}
127+
128+
/**
129+
* Holds if this algorithm is weak.
130+
*/
131+
abstract predicate isWeak();
132+
}
133+
134+
/**
135+
* A hashing algorithm such as `MD5` or `SHA512`.
136+
*/
137+
class HashingAlgorithm extends MkHashingAlgorithm, CryptographicAlgorithm {
138+
string name;
139+
boolean isWeak;
140+
141+
HashingAlgorithm() { this = MkHashingAlgorithm(name, isWeak) }
142+
143+
override string getName() { result = name }
144+
145+
override predicate isWeak() { isWeak = true }
146+
}
147+
148+
/**
149+
* An encryption algorithm such as `DES` or `AES512`.
150+
*/
151+
class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm {
152+
string name;
153+
boolean isWeak;
154+
155+
EncryptionAlgorithm() { this = MkEncryptionAlgorithm(name, isWeak) }
156+
157+
override string getName() { result = name }
158+
159+
override predicate isWeak() { isWeak = true }
160+
}
161+
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+
176+
/**
177+
* An application of a cryptographic algorithm.
178+
*/
179+
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+
185+
/**
186+
* Gets the applied algorithm.
187+
*/
188+
abstract CryptographicAlgorithm getAlgorithm();
189+
}
190+
191+
class Md5 extends CryptographicOperation {
192+
Expr input;
193+
CryptographicAlgorithm algorithm;
194+
SelectorExpr sel;
195+
CallExpr call;
196+
197+
Md5() {
198+
this = call and
199+
algorithm.matchesName(sel.getBase().toString()) and
200+
algorithm.matchesName("MD5") and
201+
sel.getSelector().toString() = call.getCalleeName().toString() and
202+
call.getArgument(0) = input
203+
}
204+
205+
override Expr getInput() { result = input }
206+
207+
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
208+
}
209+
210+
class Des extends CryptographicOperation {
211+
Expr input;
212+
CryptographicAlgorithm algorithm;
213+
CallExpr call;
214+
SelectorExpr sel;
215+
216+
Des() {
217+
this = call and
218+
algorithm.matchesName(call.getCalleeName()) and
219+
algorithm.matchesName("DES") and
220+
call.getArgument(0) = input
221+
}
222+
223+
override Expr getInput() { result = input }
224+
225+
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
226+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package main
2+
3+
import (
4+
"crypto/des"
5+
"crypto/md5"
6+
"fmt"
7+
)
8+
9+
func main() {
10+
11+
password := []byte("password")
12+
13+
var tripleDESKey []byte
14+
tripleDESKey = append(tripleDESKey, password[:16]...)
15+
tripleDESKey = append(tripleDESKey, password[:8]...)
16+
17+
// BAD, des is a weak crypto algorithm
18+
_, err := des.NewTripleDESCipher(tripleDESKey)
19+
if err != nil {
20+
panic(err)
21+
}
22+
23+
// BAD, md5 is a weak crypto algorithm
24+
fmt.Printf("%x", md5.Sum(password))
25+
26+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| BadCrypto.go:18:35:18:46 | tripleDESKey | Sensitive data is used in a broken or weak cryptographic algorithm. |
2+
| BadCrypto.go:24:27:24:34 | password | Sensitive data is used in a broken or weak cryptographic algorithm. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
experimental/CWE-327/BrokenCryptoAlgorithm.ql

0 commit comments

Comments
 (0)