adding go crypto library

This commit is contained in:
dilanbhalla
2020-08-10 11:56:41 -07:00
parent 097775bf64
commit 95342cdea7
6 changed files with 331 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
/**
* @name Use of a broken or risky cryptographic algorithm
* @description Using broken or weak cryptographic algorithms can allow an attacker to compromise security.
* @kind problem
* @problem.severity error
* @precision high
* @id go/weak-cryptographic-algorithm
* @tags security
*/
import go
import BrokenCryptoAlgorithmCustomizations::BrokenCryptoAlgorithm
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), "Sensitive data is used in a broken or weak cryptographic algorithm."

View File

@@ -0,0 +1,60 @@
/**
* Provides default sources, sinks and sanitizers for reasoning about
* sensitive information in broken or weak cryptographic algorithms,
* as well as extension points for adding your own.
*/
import go
private import semmle.go.security.SensitiveActions
private import CryptoLibraries
module BrokenCryptoAlgorithm {
/**
* A data flow source for sensitive information in broken or weak cryptographic algorithms.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for sensitive information in broken or weak cryptographic algorithms.
*/
abstract class Sink extends DataFlow::Node { }
/**
* A sanitizer for sensitive information in broken or weak cryptographic algorithms.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* A sensitive source.
*/
class SensitiveSource extends Source {
SensitiveSource() { this.asExpr() instanceof SensitiveExpr }
}
/**
* An expression used by a broken or weak cryptographic algorithm.
*/
class WeakCryptographicOperationSink extends Sink {
WeakCryptographicOperationSink() {
exists(CryptographicOperation application |
application.getAlgorithm().isWeak() and
this.asExpr() = application.getInput()
)
}
}
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "BrokenCryptoAlgorithm" }
override predicate isSource(DataFlow::Node source) { source instanceof SensitiveSource }
override predicate isSink(DataFlow::Node sink) {
sink instanceof WeakCryptographicOperationSink
}
override predicate isSanitizer(DataFlow::Node node) {
super.isSanitizer(node) or
node instanceof Sanitizer
}
}
}

View File

@@ -0,0 +1,226 @@
/**
* Provides classes for modelling cryptographic libraries.
*/
import go
/**
* Names of cryptographic algorithms, separated into strong and weak variants.
*
* The names are normalized: upper-case, no spaces, dashes or underscores.
*
* The names are inspired by the names used in real world crypto libraries.
*
* The classification into strong and weak are based on Wikipedia, OWASP and google (2017).
*/
private module AlgorithmNames {
predicate isStrongHashingAlgorithm(string name) {
name = "DSA" or
name = "ED25519" or
name = "ES256" or
name = "ECDSA256" or
name = "ES384" or
name = "ECDSA384" or
name = "ES512" or
name = "ECDSA512" or
name = "SHA2" or
name = "SHA224" or
name = "SHA256" or
name = "SHA384" or
name = "SHA512" or
name = "SHA3"
}
predicate isWeakHashingAlgorithm(string name) {
name = "HAVEL128" or
name = "MD2" or
name = "MD4" or
name = "MD5" or
name = "PANAMA" or
name = "RIPEMD" or
name = "RIPEMD128" or
name = "RIPEMD256" or
name = "RIPEMD160" or
name = "RIPEMD320" or
name = "SHA0" or
name = "SHA1"
}
predicate isStrongEncryptionAlgorithm(string name) {
name = "AES" or
name = "AES128" or
name = "AES192" or
name = "AES256" or
name = "AES512" or
name = "RSA" or
name = "RABBIT" or
name = "BLOWFISH"
}
predicate isWeakEncryptionAlgorithm(string name) {
name = "DES" or
name = "3DES" or
name = "TRIPLEDES" or
name = "TDEA" or
name = "TRIPLEDEA" or
name = "ARC2" or
name = "RC2" or
name = "ARC4" or
name = "RC4" or
name = "ARCFOUR" or
name = "ARC5" or
name = "RC5"
}
predicate isStrongPasswordHashingAlgorithm(string name) {
name = "ARGON2" or
name = "PBKDF2" or
name = "BCRYPT" or
name = "SCRYPT"
}
predicate isWeakPasswordHashingAlgorithm(string name) { none() }
}
private import AlgorithmNames
/**
* A cryptographic algorithm.
*/
private newtype TCryptographicAlgorithm =
MkHashingAlgorithm(string name, boolean isWeak) {
isStrongHashingAlgorithm(name) and isWeak = false
or
isWeakHashingAlgorithm(name) and isWeak = true
} or
MkEncryptionAlgorithm(string name, boolean isWeak) {
isStrongEncryptionAlgorithm(name) and isWeak = false
or
isWeakEncryptionAlgorithm(name) and isWeak = true
} or
MkPasswordHashingAlgorithm(string name, boolean isWeak) {
isStrongPasswordHashingAlgorithm(name) and isWeak = false
or
isWeakPasswordHashingAlgorithm(name) and isWeak = true
}
/**
* A cryptographic algorithm.
*/
abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
/** Gets a textual representation of this element. */
string toString() { result = getName() }
/**
* Gets the name of this algorithm.
*/
abstract string getName();
/**
* Holds if the name of this algorithm matches `name` modulo case,
* white space, dashes and underscores.
*/
bindingset[name]
predicate matchesName(string name) {
name.toUpperCase().regexpReplaceAll("[-_ ]", "").regexpMatch(".*" + getName() + ".*")
}
/**
* Holds if this algorithm is weak.
*/
abstract predicate isWeak();
}
/**
* A hashing algorithm such as `MD5` or `SHA512`.
*/
class HashingAlgorithm extends MkHashingAlgorithm, CryptographicAlgorithm {
string name;
boolean isWeak;
HashingAlgorithm() { this = MkHashingAlgorithm(name, isWeak) }
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
}
/**
* An encryption algorithm such as `DES` or `AES512`.
*/
class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm {
string name;
boolean isWeak;
EncryptionAlgorithm() { this = MkEncryptionAlgorithm(name, isWeak) }
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
}
/**
* A password hashing algorithm such as `PBKDF2` or `SCRYPT`.
*/
class PasswordHashingAlgorithm extends MkPasswordHashingAlgorithm, CryptographicAlgorithm {
string name;
boolean isWeak;
PasswordHashingAlgorithm() { this = MkPasswordHashingAlgorithm(name, isWeak) }
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
}
/**
* An application of a cryptographic algorithm.
*/
abstract class CryptographicOperation extends Expr {
/**
* Gets the input the algorithm is used on, e.g. the plain text input to be encrypted.
*/
abstract Expr getInput();
/**
* Gets the applied algorithm.
*/
abstract CryptographicAlgorithm getAlgorithm();
}
class Md5 extends CryptographicOperation {
Expr input;
CryptographicAlgorithm algorithm;
SelectorExpr sel;
CallExpr call;
Md5() {
this = call and
algorithm.matchesName(sel.getBase().toString()) and
algorithm.matchesName("MD5") and
sel.getSelector().toString() = call.getCalleeName().toString() and
call.getArgument(0) = input
}
override Expr getInput() { result = input }
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
}
class Des extends CryptographicOperation {
Expr input;
CryptographicAlgorithm algorithm;
CallExpr call;
SelectorExpr sel;
Des() {
this = call and
algorithm.matchesName(call.getCalleeName()) and
algorithm.matchesName("DES") and
call.getArgument(0) = input
}
override Expr getInput() { result = input }
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
}

View File

@@ -0,0 +1,26 @@
package main
import (
"crypto/des"
"crypto/md5"
"fmt"
)
func main() {
password := []byte("password")
var tripleDESKey []byte
tripleDESKey = append(tripleDESKey, password[:16]...)
tripleDESKey = append(tripleDESKey, password[:8]...)
// BAD, des is a weak crypto algorithm
_, err := des.NewTripleDESCipher(tripleDESKey)
if err != nil {
panic(err)
}
// BAD, md5 is a weak crypto algorithm
fmt.Printf("%x", md5.Sum(password))
}

View File

@@ -0,0 +1,2 @@
| BadCrypto.go:18:35:18:46 | tripleDESKey | Sensitive data is used in a broken or weak cryptographic algorithm. |
| BadCrypto.go:24:27:24:34 | password | Sensitive data is used in a broken or weak cryptographic algorithm. |

View File

@@ -0,0 +1 @@
experimental/CWE-327/BrokenCryptoAlgorithm.ql