|
4 | 4 | */ |
5 | 5 |
|
6 | 6 | import swift |
7 | | -import codeql.swift.security.SensitiveExprs |
8 | 7 | import codeql.swift.dataflow.DataFlow |
9 | | -import codeql.swift.dataflow.TaintTracking |
| 8 | +import codeql.swift.dataflow.ExternalFlow |
| 9 | +private import codeql.swift.security.WeakSensitiveDataHashingExtensions |
10 | 10 |
|
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 { |
12 | 57 | string algorithm; |
13 | 58 |
|
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) |
31 | 61 | } |
32 | 62 |
|
33 | | - string getAlgorithm() { |
34 | | - result = algorithm |
35 | | - } |
| 63 | + override string getAlgorithm() { result = algorithm } |
36 | 64 | } |
0 commit comments