|
| 1 | +/** |
| 2 | + * @name Cleartext logging of sensitive information |
| 3 | + * @description Logging sensitive information in plaintext can |
| 4 | + * expose it to an attacker. |
| 5 | + * @kind path-problem |
| 6 | + * @problem.severity error |
| 7 | + * @security-severity 7.5 |
| 8 | + * @precision high |
| 9 | + * @id swift/cleartext-logging |
| 10 | + * @tags security |
| 11 | + * external/cwe/cwe-312 |
| 12 | + * external/cwe/cwe-359 |
| 13 | + * external/cwe/cwe-532 |
| 14 | + */ |
| 15 | + |
| 16 | +// |
| 17 | +// FIXME: This is a deliberately dumb and noisy version of the query used to exercise data flow early on. |
| 18 | +// |
| 19 | +import unified |
| 20 | +import codeql.concepts.internal.SensitiveDataHeuristics |
| 21 | + |
| 22 | +private string getNameFromExpr(Expr e) { |
| 23 | + result = e.(IdentifierExpr).getValue() |
| 24 | + or |
| 25 | + result = e.(MemberAccessExpr).getMemberName() |
| 26 | +} |
| 27 | + |
| 28 | +module DummyConfig implements DataFlow::ConfigSig { |
| 29 | + predicate isSource(DataFlow::Node node) { |
| 30 | + exists(string name | |
| 31 | + name = getNameFromExpr(node.asExpr()) and |
| 32 | + HeuristicNames::nameIndicatesSensitiveData(name) |
| 33 | + ) |
| 34 | + } |
| 35 | + |
| 36 | + predicate isSink(DataFlow::Node node) { |
| 37 | + exists(CallExpr call | |
| 38 | + getNameFromExpr(call.getCallee()).regexpMatch("(?i)(ns)?(log|warn(ing)?|error|print).*") and |
| 39 | + node.asExpr() = call.getAnArgument().getValue() |
| 40 | + ) |
| 41 | + } |
| 42 | + |
| 43 | + predicate isBarrierIn(DataFlow::Node node) { isSource(node) } |
| 44 | +} |
| 45 | + |
| 46 | +module DummyFlow = TaintTracking::Global<DummyConfig>; |
| 47 | + |
| 48 | +import DummyFlow::PathGraph |
| 49 | + |
| 50 | +from DummyFlow::PathNode source, DummyFlow::PathNode sink |
| 51 | +where DummyFlow::flowPath(source, sink) |
| 52 | +select sink.getNode(), source, sink, "Logging of $@", source.getNode(), "sensitive data" |
0 commit comments