mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge pull request #10335 from github/redsun82/swift-weak-hashing-phase-1
Swift: first version of query targeting weak hashing
This commit is contained in:
@@ -1,17 +1,30 @@
|
||||
private import codeql.swift.generated.AstNode
|
||||
private import codeql.swift.elements.decl.AbstractFunctionDecl
|
||||
private import codeql.swift.elements.decl.Decl
|
||||
private import codeql.swift.generated.ParentChild
|
||||
|
||||
private Element getEnclosingFunctionStep(Element e) {
|
||||
not e instanceof AbstractFunctionDecl and
|
||||
result = getImmediateParent(e)
|
||||
}
|
||||
private module Cached {
|
||||
private Element getEnclosingDeclStep(Element e) {
|
||||
not e instanceof Decl and
|
||||
result = getImmediateParent(e)
|
||||
}
|
||||
|
||||
cached
|
||||
private AbstractFunctionDecl getEnclosingFunctionCached(AstNode ast) {
|
||||
result = getEnclosingFunctionStep*(getImmediateParent(ast))
|
||||
cached
|
||||
Decl getEnclosingDecl(AstNode ast) { result = getEnclosingDeclStep*(getImmediateParent(ast)) }
|
||||
|
||||
private Element getEnclosingFunctionStep(Element e) {
|
||||
not e instanceof AbstractFunctionDecl and
|
||||
result = getEnclosingDecl(e)
|
||||
}
|
||||
|
||||
cached
|
||||
AbstractFunctionDecl getEnclosingFunction(AstNode ast) {
|
||||
result = getEnclosingFunctionStep*(getEnclosingDecl(ast))
|
||||
}
|
||||
}
|
||||
|
||||
class AstNode extends AstNodeBase {
|
||||
final AbstractFunctionDecl getEnclosingFunction() { result = getEnclosingFunctionCached(this) }
|
||||
final AbstractFunctionDecl getEnclosingFunction() { result = Cached::getEnclosingFunction(this) }
|
||||
|
||||
final Decl getEnclosingDecl() { result = Cached::getEnclosingDecl(this) }
|
||||
}
|
||||
|
||||
@@ -121,20 +121,24 @@ class SensitiveExpr extends Expr {
|
||||
SensitiveDataType sensitiveType;
|
||||
|
||||
SensitiveExpr() {
|
||||
// variable reference
|
||||
this.(DeclRefExpr).getDecl().(SensitiveVarDecl).hasInfo(label, sensitiveType)
|
||||
or
|
||||
// member variable reference
|
||||
this.(MemberRefExpr).getMember().(SensitiveVarDecl).hasInfo(label, sensitiveType)
|
||||
or
|
||||
// function call
|
||||
this.(ApplyExpr).getStaticTarget().(SensitiveFunctionDecl).hasInfo(label, sensitiveType)
|
||||
or
|
||||
// sensitive argument
|
||||
exists(SensitiveArgument a |
|
||||
a.hasInfo(label, sensitiveType) and
|
||||
a.getExpr() = this
|
||||
)
|
||||
(
|
||||
// variable reference
|
||||
this.(DeclRefExpr).getDecl().(SensitiveVarDecl).hasInfo(label, sensitiveType)
|
||||
or
|
||||
// member variable reference
|
||||
this.(MemberRefExpr).getMember().(SensitiveVarDecl).hasInfo(label, sensitiveType)
|
||||
or
|
||||
// function call
|
||||
this.(ApplyExpr).getStaticTarget().(SensitiveFunctionDecl).hasInfo(label, sensitiveType)
|
||||
or
|
||||
// sensitive argument
|
||||
exists(SensitiveArgument a |
|
||||
a.hasInfo(label, sensitiveType) and
|
||||
a.getExpr() = this
|
||||
)
|
||||
) and
|
||||
// do not mark as sensitive it if it is probably safe
|
||||
not label.toLowerCase().regexpMatch(regexpProbablySafe())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,13 +150,6 @@ class SensitiveExpr extends Expr {
|
||||
* Gets the type of sensitive expression this is.
|
||||
*/
|
||||
SensitiveDataType getSensitiveType() { result = sensitiveType }
|
||||
|
||||
/**
|
||||
* Holds if this sensitive expression might be safe because it contains
|
||||
* hashed or encrypted data, or is only a reference to data that is stored
|
||||
* elsewhere.
|
||||
*/
|
||||
predicate isProbablySafe() { label.toLowerCase().regexpMatch(regexpProbablySafe()) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -70,12 +70,7 @@ class RealmStore extends Stored {
|
||||
class CleartextStorageConfig extends TaintTracking::Configuration {
|
||||
CleartextStorageConfig() { this = "CleartextStorageConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) {
|
||||
exists(SensitiveExpr e |
|
||||
node.asExpr() = e and
|
||||
not e.isProbablySafe()
|
||||
)
|
||||
}
|
||||
override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SensitiveExpr }
|
||||
|
||||
override predicate isSink(DataFlow::Node node) { node.asExpr() instanceof Stored }
|
||||
|
||||
|
||||
@@ -63,12 +63,7 @@ class URL extends Transmitted {
|
||||
class CleartextTransmissionConfig extends TaintTracking::Configuration {
|
||||
CleartextTransmissionConfig() { this = "CleartextTransmissionConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) {
|
||||
exists(SensitiveExpr e |
|
||||
node.asExpr() = e and
|
||||
not e.isProbablySafe()
|
||||
)
|
||||
}
|
||||
override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SensitiveExpr }
|
||||
|
||||
override predicate isSink(DataFlow::Node node) { node.asExpr() instanceof Transmitted }
|
||||
|
||||
|
||||
84
swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.qhelp
Executable file
84
swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.qhelp
Executable file
@@ -0,0 +1,84 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Using a broken or weak cryptographic hash function can leave data
|
||||
vulnerable, and should not be used in security related code.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A strong cryptographic hash function should be resistant to:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Pre-image attacks</b>. If you know a hash value <code>h(x)</code>,
|
||||
you should not be able to easily find the input <code>x</code>.
|
||||
</li>
|
||||
<li>
|
||||
<b>Collision attacks</b>. If you know a hash value <code>h(x)</code>,
|
||||
you should not be able to easily find a different input
|
||||
<code>y</code>
|
||||
with the same hash value <code>h(x) = h(y)</code>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
As an example, both MD5 and SHA-1 are known to be vulnerable to collision attacks.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Since it's OK to use a weak cryptographic hash function in a non-security
|
||||
context, this query only alerts when these are used to hash sensitive
|
||||
data (such as passwords, certificates, usernames).
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Ensure that you use a strong, modern cryptographic hash function, such as:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Argon2, scrypt, bcrypt, or PBKDF2 for passwords and other data with limited input space where
|
||||
a dictionary-like attack is feasible.
|
||||
</li>
|
||||
<li>
|
||||
SHA-2, or SHA-3 in other cases.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following examples show a function for checking whether the hash
|
||||
of a certificate matches a known value -- to prevent tampering.
|
||||
|
||||
In the first case the MD5 hashing algorithm is used that is known to be vulnerable to collision attacks.
|
||||
</p>
|
||||
<sample src="WeakSensitiveDataHashingBad.swift"/>
|
||||
<p>
|
||||
|
||||
Here is the same function using SHA-512, which is a strong cryptographic hashing function.
|
||||
</p>
|
||||
<sample src="WeakSensitiveDataHashingGood.swift"/>
|
||||
|
||||
</example>
|
||||
<references>
|
||||
<li>
|
||||
OWASP:
|
||||
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html">Password Storage
|
||||
Cheat Sheet
|
||||
</a>
|
||||
and
|
||||
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html#use-strong-cryptographic-hashing-algorithms">
|
||||
Transport Layer Protection Cheat Sheet
|
||||
</a>
|
||||
</li>
|
||||
</references>
|
||||
|
||||
</qhelp>
|
||||
63
swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql
Executable file
63
swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql
Executable file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @name Use of a broken or weak cryptographic hashing algorithm on sensitive data
|
||||
* @description Using broken or weak cryptographic hashing algorithms can compromise security.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 7.5
|
||||
* @precision high
|
||||
* @id swift/weak-sensitive-data-hashing
|
||||
* @tags security
|
||||
* external/cwe/cwe-327
|
||||
* external/cwe/cwe-328
|
||||
*/
|
||||
|
||||
import swift
|
||||
import codeql.swift.security.SensitiveExprs
|
||||
import codeql.swift.dataflow.DataFlow
|
||||
import codeql.swift.dataflow.TaintTracking
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class WeakHashingConfig extends TaintTracking::Configuration {
|
||||
WeakHashingConfig() { this = "WeakHashingConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) { node instanceof WeakHashingConfig::Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node node) { node instanceof WeakHashingConfig::Sink }
|
||||
}
|
||||
|
||||
module WeakHashingConfig {
|
||||
class Source extends DataFlow::Node {
|
||||
Source() { this.asExpr() instanceof SensitiveExpr }
|
||||
}
|
||||
|
||||
abstract class Sink extends DataFlow::Node {
|
||||
abstract string getAlgorithm();
|
||||
}
|
||||
|
||||
class CryptoHash extends Sink {
|
||||
string algorithm;
|
||||
|
||||
CryptoHash() {
|
||||
exists(ApplyExpr call, FuncDecl func |
|
||||
call.getAnArgument().getExpr() = this.asExpr() and
|
||||
call.getStaticTarget() = func and
|
||||
func.getName().matches(["hash(%", "update(%"]) and
|
||||
algorithm = func.getEnclosingDecl().(StructDecl).getName() and
|
||||
algorithm = ["MD5", "SHA1"]
|
||||
)
|
||||
}
|
||||
|
||||
override string getAlgorithm() { result = algorithm }
|
||||
}
|
||||
}
|
||||
|
||||
from
|
||||
WeakHashingConfig config, DataFlow::PathNode source, DataFlow::PathNode sink, string algorithm,
|
||||
SensitiveExpr expr
|
||||
where
|
||||
config.hasFlowPath(source, sink) and
|
||||
algorithm = sink.getNode().(WeakHashingConfig::Sink).getAlgorithm() and
|
||||
expr = source.getNode().asExpr()
|
||||
select sink.getNode(), source, sink,
|
||||
"Insecure hashing algorithm (" + algorithm + ") depends on $@.", source.getNode(),
|
||||
"sensitive data (" + expr.getSensitiveType() + " " + expr.getLabel() + ")"
|
||||
5
swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingBad.swift
Executable file
5
swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingBad.swift
Executable file
@@ -0,0 +1,5 @@
|
||||
typealias Hasher = Crypto.Insecure.MD5
|
||||
|
||||
func checkCertificate(cert: Array[UInt8], hash: Array[UInt8]) -> Bool
|
||||
return Hasher.hash(data: cert) == hash // BAD
|
||||
}
|
||||
4
swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingGood.swift
Executable file
4
swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingGood.swift
Executable file
@@ -0,0 +1,4 @@
|
||||
typealias Hasher = Crypto.SHA512
|
||||
|
||||
func checkCertificate(cert: Array[UInt8], hash: Array[UInt8]) -> Bool
|
||||
return Hasher.hash(data: cert) == hash // GOOD
|
||||
@@ -1,13 +1,8 @@
|
||||
| testCoreData.swift:48:15:48:15 | password | label:password, type:credential |
|
||||
| testCoreData.swift:49:15:49:15 | password_hash | isProbablySafe, label:password_hash, type:credential |
|
||||
| testCoreData.swift:51:24:51:24 | password | label:password, type:credential |
|
||||
| testCoreData.swift:52:24:52:24 | password_hash | isProbablySafe, label:password_hash, type:credential |
|
||||
| testCoreData.swift:58:15:58:15 | password | label:password, type:credential |
|
||||
| testCoreData.swift:59:15:59:15 | password_file | isProbablySafe, label:password_file, type:credential |
|
||||
| testCoreData.swift:61:25:61:25 | password | label:password, type:credential |
|
||||
| testCoreData.swift:62:25:62:25 | password_file | isProbablySafe, label:password_file, type:credential |
|
||||
| testCoreData.swift:64:16:64:16 | password | label:password, type:credential |
|
||||
| testCoreData.swift:65:16:65:16 | password_file | isProbablySafe, label:password_file, type:credential |
|
||||
| testCoreData.swift:77:2:77:25 | call to doSomething(password:) | label:doSomething(password:), type:credential |
|
||||
| testCoreData.swift:77:24:77:24 | x | label:password, type:credential |
|
||||
| testCoreData.swift:80:10:80:22 | call to getPassword() | label:getPassword(), type:credential |
|
||||
@@ -16,15 +11,10 @@
|
||||
| testCoreData.swift:92:10:92:10 | passwd | label:passwd, type:credential |
|
||||
| testCoreData.swift:93:10:93:10 | passwd | label:passwd, type:credential |
|
||||
| testRealm.swift:34:11:34:11 | myPassword | label:myPassword, type:credential |
|
||||
| testRealm.swift:38:11:38:11 | myHashedPassword | isProbablySafe, label:myHashedPassword, type:credential |
|
||||
| testRealm.swift:42:11:42:11 | myPassword | label:myPassword, type:credential |
|
||||
| testRealm.swift:46:11:46:11 | myHashedPassword | isProbablySafe, label:myHashedPassword, type:credential |
|
||||
| testRealm.swift:52:12:52:12 | myPassword | label:myPassword, type:credential |
|
||||
| testRealm.swift:55:12:55:12 | myHashedPassword | isProbablySafe, label:myHashedPassword, type:credential |
|
||||
| testSend.swift:29:19:29:19 | passwordPlain | label:passwordPlain, type:credential |
|
||||
| testSend.swift:30:19:30:19 | passwordHash | isProbablySafe, label:passwordHash, type:credential |
|
||||
| testSend.swift:33:19:33:19 | passwordPlain | label:passwordPlain, type:credential |
|
||||
| testSend.swift:34:19:34:19 | passwordHash | isProbablySafe, label:passwordHash, type:credential |
|
||||
| testSend.swift:45:13:45:13 | password | label:password, type:credential |
|
||||
| testSend.swift:46:13:46:13 | password | label:password, type:credential |
|
||||
| testSend.swift:47:17:47:17 | password | label:password, type:credential |
|
||||
@@ -32,6 +22,5 @@
|
||||
| testSend.swift:49:27:49:27 | password | label:password, type:credential |
|
||||
| testSend.swift:50:27:50:27 | password | label:password, type:credential |
|
||||
| testURL.swift:13:54:13:54 | passwd | label:passwd, type:credential |
|
||||
| testURL.swift:14:54:14:54 | encrypted_passwd | isProbablySafe, label:encrypted_passwd, type:credential |
|
||||
| testURL.swift:16:55:16:55 | credit_card_no | label:credit_card_no, type:private information |
|
||||
| testURL.swift:20:22:20:22 | passwd | label:passwd, type:credential |
|
||||
|
||||
@@ -5,8 +5,6 @@ string describe(SensitiveExpr e) {
|
||||
result = "label:" + e.getLabel()
|
||||
or
|
||||
result = "type:" + e.getSensitiveType().toString()
|
||||
or
|
||||
e.isProbablySafe() and result = "isProbablySafe"
|
||||
}
|
||||
|
||||
from SensitiveExpr e
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
edges
|
||||
| testCrypto.swift:56:47:56:47 | passwd : | testCrypto.swift:63:44:63:44 | passwd |
|
||||
| testCrypto.swift:60:43:60:43 | credit_card_no : | testCrypto.swift:61:43:61:43 | credit_card_no |
|
||||
| testCrypto.swift:60:43:60:43 | credit_card_no : | testCrypto.swift:61:43:61:43 | credit_card_no : |
|
||||
| testCrypto.swift:60:43:60:43 | credit_card_no : | testCrypto.swift:67:44:67:44 | credit_card_no |
|
||||
| testCrypto.swift:61:43:61:43 | credit_card_no : | testCrypto.swift:67:44:67:44 | credit_card_no |
|
||||
nodes
|
||||
| testCrypto.swift:56:47:56:47 | passwd | semmle.label | passwd |
|
||||
| testCrypto.swift:56:47:56:47 | passwd : | semmle.label | passwd : |
|
||||
| testCrypto.swift:60:43:60:43 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCrypto.swift:60:43:60:43 | credit_card_no : | semmle.label | credit_card_no : |
|
||||
| testCrypto.swift:61:43:61:43 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCrypto.swift:61:43:61:43 | credit_card_no : | semmle.label | credit_card_no : |
|
||||
| testCrypto.swift:63:44:63:44 | passwd | semmle.label | passwd |
|
||||
| testCrypto.swift:67:44:67:44 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCrypto.swift:90:23:90:23 | passwd | semmle.label | passwd |
|
||||
| testCrypto.swift:94:23:94:23 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCrypto.swift:99:23:99:23 | passwd | semmle.label | passwd |
|
||||
| testCrypto.swift:103:23:103:23 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCrypto.swift:132:32:132:32 | passwd | semmle.label | passwd |
|
||||
| testCrypto.swift:136:32:136:32 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testCrypto.swift:141:32:141:32 | passwd | semmle.label | passwd |
|
||||
| testCrypto.swift:145:32:145:32 | credit_card_no | semmle.label | credit_card_no |
|
||||
subpaths
|
||||
#select
|
||||
| testCrypto.swift:56:47:56:47 | passwd | testCrypto.swift:56:47:56:47 | passwd | testCrypto.swift:56:47:56:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:56:47:56:47 | passwd | sensitive data (credential passwd) |
|
||||
| testCrypto.swift:60:43:60:43 | credit_card_no | testCrypto.swift:60:43:60:43 | credit_card_no | testCrypto.swift:60:43:60:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:60:43:60:43 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCrypto.swift:61:43:61:43 | credit_card_no | testCrypto.swift:60:43:60:43 | credit_card_no : | testCrypto.swift:61:43:61:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:60:43:60:43 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCrypto.swift:61:43:61:43 | credit_card_no | testCrypto.swift:61:43:61:43 | credit_card_no | testCrypto.swift:61:43:61:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:61:43:61:43 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCrypto.swift:63:44:63:44 | passwd | testCrypto.swift:56:47:56:47 | passwd : | testCrypto.swift:63:44:63:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:56:47:56:47 | passwd | sensitive data (credential passwd) |
|
||||
| testCrypto.swift:63:44:63:44 | passwd | testCrypto.swift:63:44:63:44 | passwd | testCrypto.swift:63:44:63:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:63:44:63:44 | passwd | sensitive data (credential passwd) |
|
||||
| testCrypto.swift:67:44:67:44 | credit_card_no | testCrypto.swift:60:43:60:43 | credit_card_no : | testCrypto.swift:67:44:67:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:60:43:60:43 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCrypto.swift:67:44:67:44 | credit_card_no | testCrypto.swift:61:43:61:43 | credit_card_no : | testCrypto.swift:67:44:67:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:61:43:61:43 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCrypto.swift:67:44:67:44 | credit_card_no | testCrypto.swift:67:44:67:44 | credit_card_no | testCrypto.swift:67:44:67:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:67:44:67:44 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCrypto.swift:90:23:90:23 | passwd | testCrypto.swift:90:23:90:23 | passwd | testCrypto.swift:90:23:90:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:90:23:90:23 | passwd | sensitive data (credential passwd) |
|
||||
| testCrypto.swift:94:23:94:23 | credit_card_no | testCrypto.swift:94:23:94:23 | credit_card_no | testCrypto.swift:94:23:94:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:94:23:94:23 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCrypto.swift:99:23:99:23 | passwd | testCrypto.swift:99:23:99:23 | passwd | testCrypto.swift:99:23:99:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:99:23:99:23 | passwd | sensitive data (credential passwd) |
|
||||
| testCrypto.swift:103:23:103:23 | credit_card_no | testCrypto.swift:103:23:103:23 | credit_card_no | testCrypto.swift:103:23:103:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:103:23:103:23 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCrypto.swift:132:32:132:32 | passwd | testCrypto.swift:132:32:132:32 | passwd | testCrypto.swift:132:32:132:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:132:32:132:32 | passwd | sensitive data (credential passwd) |
|
||||
| testCrypto.swift:136:32:136:32 | credit_card_no | testCrypto.swift:136:32:136:32 | credit_card_no | testCrypto.swift:136:32:136:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:136:32:136:32 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
| testCrypto.swift:141:32:141:32 | passwd | testCrypto.swift:141:32:141:32 | passwd | testCrypto.swift:141:32:141:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:141:32:141:32 | passwd | sensitive data (credential passwd) |
|
||||
| testCrypto.swift:145:32:145:32 | credit_card_no | testCrypto.swift:145:32:145:32 | credit_card_no | testCrypto.swift:145:32:145:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:145:32:145:32 | credit_card_no | sensitive data (private information credit_card_no) |
|
||||
@@ -0,0 +1 @@
|
||||
queries/Security/CWE-328/WeakSensitiveDataHashing.ql
|
||||
170
swift/ql/test/query-tests/Security/CWE-328/testCrypto.swift
Normal file
170
swift/ql/test/query-tests/Security/CWE-328/testCrypto.swift
Normal file
@@ -0,0 +1,170 @@
|
||||
//codeql-extractor-options: -module-name Crypto
|
||||
|
||||
struct SHA256 {
|
||||
static func hash<D>(data: D) -> [UInt8] {
|
||||
return []
|
||||
}
|
||||
|
||||
func update<D>(data: D) {}
|
||||
func update(bufferPointer: UnsafeRawBufferPointer) {}
|
||||
func finalize() -> [UInt8] { return [] }
|
||||
}
|
||||
|
||||
struct SHA384 {
|
||||
static func hash<D>(data: D) -> [UInt8] {
|
||||
return []
|
||||
}
|
||||
|
||||
func update<D>(data: D) {}
|
||||
func update(bufferPointer: UnsafeRawBufferPointer) {}
|
||||
func finalize() -> [UInt8] { return [] }
|
||||
}
|
||||
|
||||
struct SHA512 {
|
||||
static func hash<D>(data: D) -> [UInt8] {
|
||||
return []
|
||||
}
|
||||
|
||||
func update<D>(data: D) {}
|
||||
func update(bufferPointer: UnsafeRawBufferPointer) {}
|
||||
func finalize() -> [UInt8] { return [] }
|
||||
}
|
||||
|
||||
|
||||
enum Insecure {
|
||||
struct MD5 {
|
||||
static func hash<D>(data: D) -> [UInt8] {
|
||||
return []
|
||||
}
|
||||
|
||||
func update<D>(data: D) {}
|
||||
func update(bufferPointer: UnsafeRawBufferPointer) {}
|
||||
func finalize() -> [UInt8] { return [] }
|
||||
}
|
||||
struct SHA1 {
|
||||
static func hash<D>(data: D) -> [UInt8] {
|
||||
return []
|
||||
}
|
||||
|
||||
func update<D>(data: D) {}
|
||||
func update(bufferPointer: UnsafeRawBufferPointer) {}
|
||||
func finalize() -> [UInt8] { return [] }
|
||||
}
|
||||
}
|
||||
|
||||
func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD
|
||||
hash = Crypto.Insecure.MD5.hash(data: cert) // BAD [NOT DETECTED]
|
||||
hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD [NOT DETECTED]
|
||||
hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD
|
||||
hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD
|
||||
|
||||
hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD
|
||||
hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD [NOT DETECTED]
|
||||
hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD [NOT DETECTED]
|
||||
hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD
|
||||
|
||||
hash = Crypto.SHA256.hash(data: passwd) // BAD [NOT DETECTED] not a computationally expensive hash
|
||||
hash = Crypto.SHA256.hash(data: cert) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA256.hash(data: account_no) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA256.hash(data: credit_card_no) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA256.hash(data: credit_card_no) // GOOD, computationally expensive hash not required
|
||||
|
||||
hash = Crypto.SHA384.hash(data: passwd) // BAD [NOT DETECTED] not a computationally expensive hash
|
||||
hash = Crypto.SHA384.hash(data: cert) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA384.hash(data: account_no) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA384.hash(data: credit_card_no) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA384.hash(data: credit_card_no) // GOOD, computationally expensive hash not required
|
||||
|
||||
hash = Crypto.SHA512.hash(data: passwd) // BAD [NOT DETECTED] not a computationally expensive hash
|
||||
hash = Crypto.SHA512.hash(data: cert) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA512.hash(data: account_no) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA512.hash(data: credit_card_no) // GOOD, computationally expensive hash not required
|
||||
hash = Crypto.SHA512.hash(data: credit_card_no) // GOOD, computationally expensive hash not required
|
||||
}
|
||||
|
||||
func testMD5UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.Insecure.MD5()
|
||||
hash.update(data: passwd) // BAD
|
||||
hash.update(data: cert) // BAD [NOT DETECTED]
|
||||
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(data: account_no) // BAD [NOT DETECTED]
|
||||
hash.update(data: credit_card_no) // BAD
|
||||
}
|
||||
|
||||
func testSHA1UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.Insecure.SHA1()
|
||||
hash.update(data: passwd) // BAD
|
||||
hash.update(data: cert) // BAD [NOT DETECTED]
|
||||
hash.update(data: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(data: account_no) // BAD [NOT DETECTED]
|
||||
hash.update(data: credit_card_no) // BAD
|
||||
}
|
||||
|
||||
func testSHA256UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.SHA256()
|
||||
hash.update(data: passwd) // BAD [NOT DETECTED] not a computationally expensive hash
|
||||
hash.update(data: cert) // GOOD
|
||||
hash.update(data: account_no) // GOOD
|
||||
hash.update(data: credit_card_no) // GOOD
|
||||
}
|
||||
|
||||
func testSHA384UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.SHA384()
|
||||
hash.update(data: passwd) // BAD [NOT DETECTED] not a computationally expensive hash
|
||||
hash.update(data: cert) // GOOD
|
||||
hash.update(data: account_no) // GOOD
|
||||
hash.update(data: credit_card_no) // GOOD
|
||||
}
|
||||
|
||||
func testSHA512UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) {
|
||||
var hash = Crypto.SHA512()
|
||||
hash.update(data: passwd) // BAD [NOT DETECTED] not a computationally expensive hash
|
||||
hash.update(data: cert) // GOOD
|
||||
hash.update(data: account_no) // GOOD
|
||||
hash.update(data: credit_card_no) // GOOD
|
||||
}
|
||||
|
||||
func testMD5UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
|
||||
var hash = Crypto.Insecure.MD5()
|
||||
hash.update(bufferPointer: passwd) // BAD
|
||||
hash.update(bufferPointer: cert) // BAD [NOT DETECTED]
|
||||
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(bufferPointer: account_no) // BAD [NOT DETECTED]
|
||||
hash.update(bufferPointer: credit_card_no) // BAD
|
||||
}
|
||||
|
||||
func testSHA1UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
|
||||
var hash = Crypto.Insecure.SHA1()
|
||||
hash.update(bufferPointer: passwd) // BAD
|
||||
hash.update(bufferPointer: cert) // BAD [NOT DETECTED]
|
||||
hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive)
|
||||
hash.update(bufferPointer: account_no) // BAD [NOT DETECTED]
|
||||
hash.update(bufferPointer: credit_card_no) // BAD
|
||||
}
|
||||
|
||||
func testSHA256UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
|
||||
var hash = Crypto.SHA256()
|
||||
hash.update(bufferPointer: passwd) // BAD [NOT DETECTED] not a computationally expensive hash
|
||||
hash.update(bufferPointer: cert) // GOOD
|
||||
hash.update(bufferPointer: account_no) // GOOD
|
||||
hash.update(bufferPointer: credit_card_no) // GOOD
|
||||
}
|
||||
|
||||
func testSHA384UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
|
||||
var hash = Crypto.SHA384()
|
||||
hash.update(bufferPointer: passwd) // BAD [NOT DETECTED] not a computationally expensive hash
|
||||
hash.update(bufferPointer: cert) // GOOD
|
||||
hash.update(bufferPointer: account_no) // GOOD
|
||||
hash.update(bufferPointer: credit_card_no) // GOOD
|
||||
}
|
||||
|
||||
func testSHA512UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) {
|
||||
var hash = Crypto.SHA512()
|
||||
hash.update(bufferPointer: passwd) // BAD [NOT DETECTED] not a computationally expensive hash
|
||||
hash.update(bufferPointer: cert) // GOOD
|
||||
hash.update(bufferPointer: account_no) // GOOD
|
||||
hash.update(bufferPointer: credit_card_no) // GOOD
|
||||
}
|
||||
Reference in New Issue
Block a user