Skip to content

Commit b5a45c6

Browse files
committed
Swift: Define barriers, additional flow steps and sinks.
1 parent e5bf929 commit b5a45c6

File tree

2 files changed

+57
-23
lines changed

2 files changed

+57
-23
lines changed

swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,61 @@
44
*/
55

66
import swift
7-
import codeql.swift.security.SensitiveExprs
87
import codeql.swift.dataflow.DataFlow
9-
import codeql.swift.dataflow.TaintTracking
8+
import codeql.swift.dataflow.ExternalFlow
9+
private import codeql.swift.security.WeakSensitiveDataHashingExtensions
1010

11-
class WeakPasswordHashingSink extends DataFlow::Node {
11+
/**
12+
* A dataflow sink for weak password hashing vulnerabilities. That is,
13+
* a `DataFlow::Node` that is passed into a weak password hashing function.
14+
*/
15+
abstract class WeakPasswordHashingSink extends DataFlow::Node {
16+
/**
17+
* Gets the name of the hashing algorithm, for display.
18+
*/
19+
abstract string getAlgorithm();
20+
}
21+
22+
/**
23+
* A barrier for weak password hashing vulnerabilities.
24+
*/
25+
abstract class WeakPasswordHashingBarrier extends DataFlow::Node { }
26+
27+
/**
28+
* A unit class for adding additional flow steps.
29+
*/
30+
class WeakPasswordHashingAdditionalFlowStep extends Unit {
31+
/**
32+
* Holds if the step from `node1` to `node2` should be considered a flow
33+
* step for paths related to weak password hashing vulnerabilities.
34+
*/
35+
abstract predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo);
36+
}
37+
38+
/**
39+
* A sink inherited from weak sensitive data hashing. Password hashing has
40+
* stronger requirements than sensitive data hashing, since (in addition to
41+
* its particular qualities) a password *is* sensitive data. Thus, any sink
42+
* for the weak sensitive data hashing query is a sink for weak password
43+
* hashing as well.
44+
*/
45+
private class InheritedWeakPasswordHashingSink extends WeakPasswordHashingSink {
46+
InheritedWeakPasswordHashingSink() {
47+
this instanceof WeakSensitiveDataHashingSink
48+
}
49+
50+
override string getAlgorithm() { result = this.(WeakSensitiveDataHashingSink).getAlgorithm() }
51+
}
52+
53+
/**
54+
* A sink defined in a CSV model.
55+
*/
56+
private class DefaultWeakPasswordHashingSink extends WeakPasswordHashingSink {
1257
string algorithm;
1358

14-
WeakPasswordHashingSink() {
15-
// a call to System.Security.Cryptography.MD5/SHA*.ComputeHash/ComputeHashAsync/HashData/HashDataAsync
16-
exists(MethodCall call, string name |
17-
(
18-
call.getTarget().getName() = name
19-
and name in ["ComputeHash", "ComputeHashAsync", "HashData", "HashDataAsync"]
20-
)
21-
// with this as the first argument - not arg 0, since arg 0 is 'this' for methods
22-
and call.getArgument(0) = this.asExpr()
23-
and
24-
// the call is to a method in the System.Security.Cryptography.MD* class
25-
// or the System.Security.Cryptography.SHA* classes
26-
(
27-
call.getQualifier().getType().getName() = algorithm
28-
and algorithm.matches(["MD%","SHA%"])
29-
)
30-
)
59+
DefaultWeakPasswordHashingSink() {
60+
sinkNode(this, "weak-password-hash-input-" + algorithm)
3161
}
3262

33-
string getAlgorithm() {
34-
result = algorithm
35-
}
63+
override string getAlgorithm() { result = algorithm }
3664
}

swift/ql/lib/codeql/swift/security/WeakPasswordHashingQuery.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ module WeakHashingPasswordConfig implements DataFlow::ConfigSig {
1818

1919
predicate isSink(DataFlow::Node node) { node instanceof WeakPasswordHashingSink }
2020

21+
predicate isBarrier(DataFlow::Node node) { node instanceof WeakPasswordHashingBarrier }
22+
2123
predicate isBarrierIn(DataFlow::Node node) {
2224
// make sources barriers so that we only report the closest instance
2325
isSource(node)
@@ -27,6 +29,10 @@ module WeakHashingPasswordConfig implements DataFlow::ConfigSig {
2729
// make sinks barriers so that we only report the closest instance
2830
isSink(node)
2931
}
32+
33+
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
34+
any(WeakPasswordHashingAdditionalFlowStep s).step(nodeFrom, nodeTo)
35+
}
3036
}
3137

3238
module WeakHashingFlow = TaintTracking::Global<WeakHashingPasswordConfig>;

0 commit comments

Comments
 (0)