diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index c1984e0b80f7..c4a2f2dfd2fd 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -108,12 +108,20 @@ private module Cached { localFlowSsaInput(nodeFrom, def, nodeTo.asDefinition()) ) or + // flow through writes to inout parameters exists(ParamReturnKind kind, ExprCfgNode arg | arg = nodeFrom.(InOutUpdateNode).getCall(kind).asCall().getArgument(kind.getIndex()) and nodeTo.asDefinition().(Ssa::WriteDefinition).isInoutDef(arg) ) or + // flow through `&` (inout argument) nodeFrom.asExpr() = nodeTo.asExpr().(InOutExpr).getSubExpr() + or + // flow through `try!` and similar constructs + nodeFrom.asExpr() = nodeTo.asExpr().(AnyTryExpr).getSubExpr() + or + // flow through `!` + nodeFrom.asExpr() = nodeTo.asExpr().(ForceValueExpr).getSubExpr() } /** diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll index 58e29b61bba4..1292e0cf1814 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll @@ -41,6 +41,23 @@ private module Cached { nodeTo.asExpr() = interpolated and nodeFrom.asExpr() = interpolated.getAppendingExpr() ) + or + // allow flow through string concatenation. + exists(AddExpr ae | + ae.getAnOperand() = nodeFrom.asExpr() and + ae = nodeTo.asExpr() and + ae.getType().getName() = "String" + ) + or + // allow flow through `URL.init`. + exists(CallExpr call, ClassDecl c, AbstractFunctionDecl f | + c.getName() = "URL" and + c.getAMember() = f and + f.getName() = ["init(string:)", "init(string:relativeTo:)"] and + call.getFunction().(ApplyExpr).getStaticTarget() = f and + nodeFrom.asExpr() = call.getAnArgument().getExpr() and + nodeTo.asExpr() = call + ) } /** diff --git a/swift/ql/src/queries/Security/CWE-079/UnsafeWebViewFetch.ql b/swift/ql/src/queries/Security/CWE-079/UnsafeWebViewFetch.ql index b952a0c74c38..37bf5ec21c47 100644 --- a/swift/ql/src/queries/Security/CWE-079/UnsafeWebViewFetch.ql +++ b/swift/ql/src/queries/Security/CWE-079/UnsafeWebViewFetch.ql @@ -81,30 +81,6 @@ class UnsafeWebViewFetchConfig extends TaintTracking::Configuration { node instanceof Sink or node.asExpr() = any(Sink s).getBaseUrl() } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - // allow flow through `try!` and similar constructs - // TODO: this should probably be part of DataFlow / TaintTracking. - node1.asExpr() = node2.asExpr().(AnyTryExpr).getSubExpr() - or - // allow flow through `!` - // TODO: this should probably be part of DataFlow / TaintTracking. - node1.asExpr() = node2.asExpr().(ForceValueExpr).getSubExpr() - or - // allow flow through string concatenation. - // TODO: this should probably be part of TaintTracking. - node2.asExpr().(AddExpr).getAnOperand() = node1.asExpr() - or - // allow flow through `URL.init`. - exists(CallExpr call, ClassDecl c, AbstractFunctionDecl f | - c.getName() = "URL" and - c.getAMember() = f and - f.getName() = ["init(string:)", "init(string:relativeTo:)"] and - call.getFunction().(ApplyExpr).getStaticTarget() = f and - node1.asExpr() = call.getAnArgument().getExpr() and - node2.asExpr() = call - ) - } } from diff --git a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected index 6796c2e8c40a..a7c44e9b5667 100644 --- a/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected @@ -1,121 +1,222 @@ -| file://:0:0:0:0 | Phi | test.swift:7:14:7:14 | $interpolation | -| file://:0:0:0:0 | Phi | test.swift:9:14:9:14 | $interpolation | -| file://:0:0:0:0 | Phi | test.swift:11:14:11:14 | $interpolation | -| file://:0:0:0:0 | Phi | test.swift:14:14:14:14 | $interpolation | -| file://:0:0:0:0 | Phi | test.swift:16:14:16:14 | $interpolation | -| file://:0:0:0:0 | Phi | test.swift:18:14:18:14 | $interpolation | -| file://:0:0:0:0 | Phi | test.swift:21:14:21:14 | $interpolation | -| test.swift:5:7:5:7 | WriteDef | test.swift:7:16:7:16 | x | -| test.swift:5:11:5:18 | call to source() | test.swift:5:7:5:7 | WriteDef | -| test.swift:7:13:7:13 | WriteDef | file://:0:0:0:0 | Phi | -| test.swift:7:14:7:14 | $interpolation | test.swift:7:14:7:14 | &... | -| test.swift:7:14:7:14 | : &... | test.swift:7:14:7:14 | WriteDef | -| test.swift:7:14:7:14 | WriteDef | test.swift:7:15:7:15 | $interpolation | -| test.swift:7:15:7:15 | $interpolation | test.swift:7:15:7:15 | &... | -| test.swift:7:15:7:15 | : &... | test.swift:7:15:7:15 | WriteDef | -| test.swift:7:15:7:15 | WriteDef | test.swift:7:18:7:18 | $interpolation | -| test.swift:7:16:7:16 | x | test.swift:9:16:9:16 | x | -| test.swift:7:18:7:18 | $interpolation | test.swift:7:18:7:18 | &... | -| test.swift:7:18:7:18 | : &... | test.swift:7:18:7:18 | WriteDef | -| test.swift:7:18:7:18 | WriteDef | test.swift:7:13:7:13 | TapExpr | -| test.swift:9:13:9:13 | WriteDef | file://:0:0:0:0 | Phi | -| test.swift:9:14:9:14 | $interpolation | test.swift:9:14:9:14 | &... | -| test.swift:9:14:9:14 | : &... | test.swift:9:14:9:14 | WriteDef | -| test.swift:9:14:9:14 | WriteDef | test.swift:9:15:9:15 | $interpolation | -| test.swift:9:15:9:15 | $interpolation | test.swift:9:15:9:15 | &... | -| test.swift:9:15:9:15 | : &... | test.swift:9:15:9:15 | WriteDef | -| test.swift:9:15:9:15 | WriteDef | test.swift:9:18:9:18 | $interpolation | -| test.swift:9:16:9:16 | x | test.swift:9:21:9:21 | x | -| test.swift:9:18:9:18 | $interpolation | test.swift:9:18:9:18 | &... | -| test.swift:9:18:9:18 | : &... | test.swift:9:18:9:18 | WriteDef | -| test.swift:9:18:9:18 | WriteDef | test.swift:9:20:9:20 | $interpolation | -| test.swift:9:20:9:20 | $interpolation | test.swift:9:20:9:20 | &... | -| test.swift:9:20:9:20 | : &... | test.swift:9:20:9:20 | WriteDef | -| test.swift:9:20:9:20 | WriteDef | test.swift:9:23:9:23 | $interpolation | -| test.swift:9:21:9:21 | x | test.swift:11:16:11:16 | x | -| test.swift:9:23:9:23 | $interpolation | test.swift:9:23:9:23 | &... | -| test.swift:9:23:9:23 | : &... | test.swift:9:23:9:23 | WriteDef | -| test.swift:9:23:9:23 | WriteDef | test.swift:9:13:9:13 | TapExpr | -| test.swift:11:13:11:13 | WriteDef | file://:0:0:0:0 | Phi | -| test.swift:11:14:11:14 | $interpolation | test.swift:11:14:11:14 | &... | -| test.swift:11:14:11:14 | : &... | test.swift:11:14:11:14 | WriteDef | -| test.swift:11:14:11:14 | WriteDef | test.swift:11:15:11:15 | $interpolation | -| test.swift:11:15:11:15 | $interpolation | test.swift:11:15:11:15 | &... | -| test.swift:11:15:11:15 | : &... | test.swift:11:15:11:15 | WriteDef | -| test.swift:11:15:11:15 | WriteDef | test.swift:11:18:11:18 | $interpolation | -| test.swift:11:16:11:16 | x | test.swift:11:26:11:26 | x | -| test.swift:11:18:11:18 | $interpolation | test.swift:11:18:11:18 | &... | -| test.swift:11:18:11:18 | : &... | test.swift:11:18:11:18 | WriteDef | -| test.swift:11:18:11:18 | WriteDef | test.swift:11:20:11:20 | $interpolation | -| test.swift:11:20:11:20 | $interpolation | test.swift:11:20:11:20 | &... | -| test.swift:11:20:11:20 | : &... | test.swift:11:20:11:20 | WriteDef | -| test.swift:11:20:11:20 | WriteDef | test.swift:11:23:11:23 | $interpolation | -| test.swift:11:23:11:23 | $interpolation | test.swift:11:23:11:23 | &... | -| test.swift:11:23:11:23 | : &... | test.swift:11:23:11:23 | WriteDef | -| test.swift:11:23:11:23 | WriteDef | test.swift:11:25:11:25 | $interpolation | -| test.swift:11:25:11:25 | $interpolation | test.swift:11:25:11:25 | &... | -| test.swift:11:25:11:25 | : &... | test.swift:11:25:11:25 | WriteDef | -| test.swift:11:25:11:25 | WriteDef | test.swift:11:28:11:28 | $interpolation | -| test.swift:11:26:11:26 | x | test.swift:16:16:16:16 | x | -| test.swift:11:28:11:28 | $interpolation | test.swift:11:28:11:28 | &... | -| test.swift:11:28:11:28 | : &... | test.swift:11:28:11:28 | WriteDef | -| test.swift:11:28:11:28 | WriteDef | test.swift:11:13:11:13 | TapExpr | -| test.swift:13:7:13:7 | WriteDef | test.swift:14:16:14:16 | y | -| test.swift:13:11:13:11 | 42 | test.swift:13:7:13:7 | WriteDef | -| test.swift:14:13:14:13 | WriteDef | file://:0:0:0:0 | Phi | -| test.swift:14:14:14:14 | $interpolation | test.swift:14:14:14:14 | &... | -| test.swift:14:14:14:14 | : &... | test.swift:14:14:14:14 | WriteDef | -| test.swift:14:14:14:14 | WriteDef | test.swift:14:15:14:15 | $interpolation | -| test.swift:14:15:14:15 | $interpolation | test.swift:14:15:14:15 | &... | -| test.swift:14:15:14:15 | : &... | test.swift:14:15:14:15 | WriteDef | -| test.swift:14:15:14:15 | WriteDef | test.swift:14:18:14:18 | $interpolation | -| test.swift:14:16:14:16 | y | test.swift:16:27:16:27 | y | -| test.swift:14:18:14:18 | $interpolation | test.swift:14:18:14:18 | &... | -| test.swift:14:18:14:18 | : &... | test.swift:14:18:14:18 | WriteDef | -| test.swift:14:18:14:18 | WriteDef | test.swift:14:13:14:13 | TapExpr | -| test.swift:16:13:16:13 | WriteDef | file://:0:0:0:0 | Phi | -| test.swift:16:14:16:14 | $interpolation | test.swift:16:14:16:14 | &... | -| test.swift:16:14:16:14 | : &... | test.swift:16:14:16:14 | WriteDef | -| test.swift:16:14:16:14 | WriteDef | test.swift:16:15:16:15 | $interpolation | -| test.swift:16:15:16:15 | $interpolation | test.swift:16:15:16:15 | &... | -| test.swift:16:15:16:15 | : &... | test.swift:16:15:16:15 | WriteDef | -| test.swift:16:15:16:15 | WriteDef | test.swift:16:18:16:18 | $interpolation | -| test.swift:16:16:16:16 | x | test.swift:18:27:18:27 | x | -| test.swift:16:18:16:18 | $interpolation | test.swift:16:18:16:18 | &... | -| test.swift:16:18:16:18 | : &... | test.swift:16:18:16:18 | WriteDef | -| test.swift:16:18:16:18 | WriteDef | test.swift:16:26:16:26 | $interpolation | -| test.swift:16:26:16:26 | $interpolation | test.swift:16:26:16:26 | &... | -| test.swift:16:26:16:26 | : &... | test.swift:16:26:16:26 | WriteDef | -| test.swift:16:26:16:26 | WriteDef | test.swift:16:29:16:29 | $interpolation | -| test.swift:16:27:16:27 | y | test.swift:18:16:18:16 | y | -| test.swift:16:29:16:29 | $interpolation | test.swift:16:29:16:29 | &... | -| test.swift:16:29:16:29 | : &... | test.swift:16:29:16:29 | WriteDef | -| test.swift:16:29:16:29 | WriteDef | test.swift:16:13:16:13 | TapExpr | -| test.swift:18:13:18:13 | WriteDef | file://:0:0:0:0 | Phi | -| test.swift:18:14:18:14 | $interpolation | test.swift:18:14:18:14 | &... | -| test.swift:18:14:18:14 | : &... | test.swift:18:14:18:14 | WriteDef | -| test.swift:18:14:18:14 | WriteDef | test.swift:18:15:18:15 | $interpolation | -| test.swift:18:15:18:15 | $interpolation | test.swift:18:15:18:15 | &... | -| test.swift:18:15:18:15 | : &... | test.swift:18:15:18:15 | WriteDef | -| test.swift:18:15:18:15 | WriteDef | test.swift:18:18:18:18 | $interpolation | -| test.swift:18:18:18:18 | $interpolation | test.swift:18:18:18:18 | &... | -| test.swift:18:18:18:18 | : &... | test.swift:18:18:18:18 | WriteDef | -| test.swift:18:18:18:18 | WriteDef | test.swift:18:26:18:26 | $interpolation | -| test.swift:18:26:18:26 | $interpolation | test.swift:18:26:18:26 | &... | -| test.swift:18:26:18:26 | : &... | test.swift:18:26:18:26 | WriteDef | -| test.swift:18:26:18:26 | WriteDef | test.swift:18:29:18:29 | $interpolation | -| test.swift:18:29:18:29 | $interpolation | test.swift:18:29:18:29 | &... | -| test.swift:18:29:18:29 | : &... | test.swift:18:29:18:29 | WriteDef | -| test.swift:18:29:18:29 | WriteDef | test.swift:18:13:18:13 | TapExpr | -| test.swift:20:3:20:7 | WriteDef | test.swift:21:16:21:16 | x | -| test.swift:20:7:20:7 | 0 | test.swift:20:3:20:7 | WriteDef | -| test.swift:21:13:21:13 | WriteDef | file://:0:0:0:0 | Phi | -| test.swift:21:14:21:14 | $interpolation | test.swift:21:14:21:14 | &... | -| test.swift:21:14:21:14 | : &... | test.swift:21:14:21:14 | WriteDef | -| test.swift:21:14:21:14 | WriteDef | test.swift:21:15:21:15 | $interpolation | -| test.swift:21:15:21:15 | $interpolation | test.swift:21:15:21:15 | &... | -| test.swift:21:15:21:15 | : &... | test.swift:21:15:21:15 | WriteDef | -| test.swift:21:15:21:15 | WriteDef | test.swift:21:18:21:18 | $interpolation | -| test.swift:21:18:21:18 | $interpolation | test.swift:21:18:21:18 | &... | -| test.swift:21:18:21:18 | : &... | test.swift:21:18:21:18 | WriteDef | -| test.swift:21:18:21:18 | WriteDef | test.swift:21:13:21:13 | TapExpr | +| data.swift:12:6:12:6 | WriteDef | data.swift:16:12:16:12 | dataClean | +| data.swift:12:18:12:36 | call to ... | data.swift:12:6:12:6 | WriteDef | +| data.swift:13:6:13:6 | WriteDef | data.swift:14:26:14:26 | dataTainted | +| data.swift:13:20:13:38 | call to ... | data.swift:13:6:13:6 | WriteDef | +| data.swift:14:6:14:6 | WriteDef | data.swift:18:12:18:12 | dataTainted2 | +| data.swift:14:21:14:37 | call to ... | data.swift:14:6:14:6 | WriteDef | +| data.swift:14:26:14:26 | dataTainted | data.swift:17:12:17:12 | dataTainted | +| data.swift:16:12:16:12 | dataClean | data.swift:20:33:20:33 | dataClean | +| file://:0:0:0:0 | Phi | string.swift:7:14:7:14 | $interpolation | +| file://:0:0:0:0 | Phi | string.swift:9:14:9:14 | $interpolation | +| file://:0:0:0:0 | Phi | string.swift:11:14:11:14 | $interpolation | +| file://:0:0:0:0 | Phi | string.swift:14:14:14:14 | $interpolation | +| file://:0:0:0:0 | Phi | string.swift:16:14:16:14 | $interpolation | +| file://:0:0:0:0 | Phi | string.swift:18:14:18:14 | $interpolation | +| file://:0:0:0:0 | Phi | string.swift:21:14:21:14 | $interpolation | +| string.swift:5:7:5:7 | WriteDef | string.swift:7:16:7:16 | x | +| string.swift:5:11:5:18 | call to source() | string.swift:5:7:5:7 | WriteDef | +| string.swift:7:13:7:13 | WriteDef | file://:0:0:0:0 | Phi | +| string.swift:7:14:7:14 | $interpolation | string.swift:7:14:7:14 | &... | +| string.swift:7:14:7:14 | : &... | string.swift:7:14:7:14 | WriteDef | +| string.swift:7:14:7:14 | WriteDef | string.swift:7:15:7:15 | $interpolation | +| string.swift:7:15:7:15 | $interpolation | string.swift:7:15:7:15 | &... | +| string.swift:7:15:7:15 | : &... | string.swift:7:15:7:15 | WriteDef | +| string.swift:7:15:7:15 | WriteDef | string.swift:7:18:7:18 | $interpolation | +| string.swift:7:16:7:16 | x | string.swift:9:16:9:16 | x | +| string.swift:7:18:7:18 | $interpolation | string.swift:7:18:7:18 | &... | +| string.swift:7:18:7:18 | : &... | string.swift:7:18:7:18 | WriteDef | +| string.swift:7:18:7:18 | WriteDef | string.swift:7:13:7:13 | TapExpr | +| string.swift:9:13:9:13 | WriteDef | file://:0:0:0:0 | Phi | +| string.swift:9:14:9:14 | $interpolation | string.swift:9:14:9:14 | &... | +| string.swift:9:14:9:14 | : &... | string.swift:9:14:9:14 | WriteDef | +| string.swift:9:14:9:14 | WriteDef | string.swift:9:15:9:15 | $interpolation | +| string.swift:9:15:9:15 | $interpolation | string.swift:9:15:9:15 | &... | +| string.swift:9:15:9:15 | : &... | string.swift:9:15:9:15 | WriteDef | +| string.swift:9:15:9:15 | WriteDef | string.swift:9:18:9:18 | $interpolation | +| string.swift:9:16:9:16 | x | string.swift:9:21:9:21 | x | +| string.swift:9:18:9:18 | $interpolation | string.swift:9:18:9:18 | &... | +| string.swift:9:18:9:18 | : &... | string.swift:9:18:9:18 | WriteDef | +| string.swift:9:18:9:18 | WriteDef | string.swift:9:20:9:20 | $interpolation | +| string.swift:9:20:9:20 | $interpolation | string.swift:9:20:9:20 | &... | +| string.swift:9:20:9:20 | : &... | string.swift:9:20:9:20 | WriteDef | +| string.swift:9:20:9:20 | WriteDef | string.swift:9:23:9:23 | $interpolation | +| string.swift:9:21:9:21 | x | string.swift:11:16:11:16 | x | +| string.swift:9:23:9:23 | $interpolation | string.swift:9:23:9:23 | &... | +| string.swift:9:23:9:23 | : &... | string.swift:9:23:9:23 | WriteDef | +| string.swift:9:23:9:23 | WriteDef | string.swift:9:13:9:13 | TapExpr | +| string.swift:11:13:11:13 | WriteDef | file://:0:0:0:0 | Phi | +| string.swift:11:14:11:14 | $interpolation | string.swift:11:14:11:14 | &... | +| string.swift:11:14:11:14 | : &... | string.swift:11:14:11:14 | WriteDef | +| string.swift:11:14:11:14 | WriteDef | string.swift:11:15:11:15 | $interpolation | +| string.swift:11:15:11:15 | $interpolation | string.swift:11:15:11:15 | &... | +| string.swift:11:15:11:15 | : &... | string.swift:11:15:11:15 | WriteDef | +| string.swift:11:15:11:15 | WriteDef | string.swift:11:18:11:18 | $interpolation | +| string.swift:11:16:11:16 | x | string.swift:11:26:11:26 | x | +| string.swift:11:18:11:18 | $interpolation | string.swift:11:18:11:18 | &... | +| string.swift:11:18:11:18 | : &... | string.swift:11:18:11:18 | WriteDef | +| string.swift:11:18:11:18 | WriteDef | string.swift:11:20:11:20 | $interpolation | +| string.swift:11:20:11:20 | $interpolation | string.swift:11:20:11:20 | &... | +| string.swift:11:20:11:20 | : &... | string.swift:11:20:11:20 | WriteDef | +| string.swift:11:20:11:20 | WriteDef | string.swift:11:23:11:23 | $interpolation | +| string.swift:11:23:11:23 | $interpolation | string.swift:11:23:11:23 | &... | +| string.swift:11:23:11:23 | : &... | string.swift:11:23:11:23 | WriteDef | +| string.swift:11:23:11:23 | WriteDef | string.swift:11:25:11:25 | $interpolation | +| string.swift:11:25:11:25 | $interpolation | string.swift:11:25:11:25 | &... | +| string.swift:11:25:11:25 | : &... | string.swift:11:25:11:25 | WriteDef | +| string.swift:11:25:11:25 | WriteDef | string.swift:11:28:11:28 | $interpolation | +| string.swift:11:26:11:26 | x | string.swift:16:16:16:16 | x | +| string.swift:11:28:11:28 | $interpolation | string.swift:11:28:11:28 | &... | +| string.swift:11:28:11:28 | : &... | string.swift:11:28:11:28 | WriteDef | +| string.swift:11:28:11:28 | WriteDef | string.swift:11:13:11:13 | TapExpr | +| string.swift:13:7:13:7 | WriteDef | string.swift:14:16:14:16 | y | +| string.swift:13:11:13:11 | 42 | string.swift:13:7:13:7 | WriteDef | +| string.swift:14:13:14:13 | WriteDef | file://:0:0:0:0 | Phi | +| string.swift:14:14:14:14 | $interpolation | string.swift:14:14:14:14 | &... | +| string.swift:14:14:14:14 | : &... | string.swift:14:14:14:14 | WriteDef | +| string.swift:14:14:14:14 | WriteDef | string.swift:14:15:14:15 | $interpolation | +| string.swift:14:15:14:15 | $interpolation | string.swift:14:15:14:15 | &... | +| string.swift:14:15:14:15 | : &... | string.swift:14:15:14:15 | WriteDef | +| string.swift:14:15:14:15 | WriteDef | string.swift:14:18:14:18 | $interpolation | +| string.swift:14:16:14:16 | y | string.swift:16:27:16:27 | y | +| string.swift:14:18:14:18 | $interpolation | string.swift:14:18:14:18 | &... | +| string.swift:14:18:14:18 | : &... | string.swift:14:18:14:18 | WriteDef | +| string.swift:14:18:14:18 | WriteDef | string.swift:14:13:14:13 | TapExpr | +| string.swift:16:13:16:13 | WriteDef | file://:0:0:0:0 | Phi | +| string.swift:16:14:16:14 | $interpolation | string.swift:16:14:16:14 | &... | +| string.swift:16:14:16:14 | : &... | string.swift:16:14:16:14 | WriteDef | +| string.swift:16:14:16:14 | WriteDef | string.swift:16:15:16:15 | $interpolation | +| string.swift:16:15:16:15 | $interpolation | string.swift:16:15:16:15 | &... | +| string.swift:16:15:16:15 | : &... | string.swift:16:15:16:15 | WriteDef | +| string.swift:16:15:16:15 | WriteDef | string.swift:16:18:16:18 | $interpolation | +| string.swift:16:16:16:16 | x | string.swift:18:27:18:27 | x | +| string.swift:16:18:16:18 | $interpolation | string.swift:16:18:16:18 | &... | +| string.swift:16:18:16:18 | : &... | string.swift:16:18:16:18 | WriteDef | +| string.swift:16:18:16:18 | WriteDef | string.swift:16:26:16:26 | $interpolation | +| string.swift:16:26:16:26 | $interpolation | string.swift:16:26:16:26 | &... | +| string.swift:16:26:16:26 | : &... | string.swift:16:26:16:26 | WriteDef | +| string.swift:16:26:16:26 | WriteDef | string.swift:16:29:16:29 | $interpolation | +| string.swift:16:27:16:27 | y | string.swift:18:16:18:16 | y | +| string.swift:16:29:16:29 | $interpolation | string.swift:16:29:16:29 | &... | +| string.swift:16:29:16:29 | : &... | string.swift:16:29:16:29 | WriteDef | +| string.swift:16:29:16:29 | WriteDef | string.swift:16:13:16:13 | TapExpr | +| string.swift:18:13:18:13 | WriteDef | file://:0:0:0:0 | Phi | +| string.swift:18:14:18:14 | $interpolation | string.swift:18:14:18:14 | &... | +| string.swift:18:14:18:14 | : &... | string.swift:18:14:18:14 | WriteDef | +| string.swift:18:14:18:14 | WriteDef | string.swift:18:15:18:15 | $interpolation | +| string.swift:18:15:18:15 | $interpolation | string.swift:18:15:18:15 | &... | +| string.swift:18:15:18:15 | : &... | string.swift:18:15:18:15 | WriteDef | +| string.swift:18:15:18:15 | WriteDef | string.swift:18:18:18:18 | $interpolation | +| string.swift:18:18:18:18 | $interpolation | string.swift:18:18:18:18 | &... | +| string.swift:18:18:18:18 | : &... | string.swift:18:18:18:18 | WriteDef | +| string.swift:18:18:18:18 | WriteDef | string.swift:18:26:18:26 | $interpolation | +| string.swift:18:26:18:26 | $interpolation | string.swift:18:26:18:26 | &... | +| string.swift:18:26:18:26 | : &... | string.swift:18:26:18:26 | WriteDef | +| string.swift:18:26:18:26 | WriteDef | string.swift:18:29:18:29 | $interpolation | +| string.swift:18:29:18:29 | $interpolation | string.swift:18:29:18:29 | &... | +| string.swift:18:29:18:29 | : &... | string.swift:18:29:18:29 | WriteDef | +| string.swift:18:29:18:29 | WriteDef | string.swift:18:13:18:13 | TapExpr | +| string.swift:20:3:20:7 | WriteDef | string.swift:21:16:21:16 | x | +| string.swift:20:7:20:7 | 0 | string.swift:20:3:20:7 | WriteDef | +| string.swift:21:13:21:13 | WriteDef | file://:0:0:0:0 | Phi | +| string.swift:21:14:21:14 | $interpolation | string.swift:21:14:21:14 | &... | +| string.swift:21:14:21:14 | : &... | string.swift:21:14:21:14 | WriteDef | +| string.swift:21:14:21:14 | WriteDef | string.swift:21:15:21:15 | $interpolation | +| string.swift:21:15:21:15 | $interpolation | string.swift:21:15:21:15 | &... | +| string.swift:21:15:21:15 | : &... | string.swift:21:15:21:15 | WriteDef | +| string.swift:21:15:21:15 | WriteDef | string.swift:21:18:21:18 | $interpolation | +| string.swift:21:18:21:18 | $interpolation | string.swift:21:18:21:18 | &... | +| string.swift:21:18:21:18 | : &... | string.swift:21:18:21:18 | WriteDef | +| string.swift:21:18:21:18 | WriteDef | string.swift:21:13:21:13 | TapExpr | +| string.swift:27:7:27:7 | WriteDef | string.swift:30:13:30:13 | clean | +| string.swift:27:15:27:15 | abcdef | string.swift:27:7:27:7 | WriteDef | +| string.swift:28:7:28:7 | WriteDef | string.swift:31:13:31:13 | tainted | +| string.swift:28:17:28:25 | call to source2() | string.swift:28:7:28:7 | WriteDef | +| string.swift:30:13:30:13 | clean | string.swift:33:13:33:13 | clean | +| string.swift:31:13:31:13 | tainted | string.swift:34:21:34:21 | tainted | +| string.swift:33:13:33:13 | clean | string.swift:33:21:33:21 | clean | +| string.swift:33:21:33:21 | clean | string.swift:34:13:34:13 | clean | +| string.swift:34:13:34:13 | clean | string.swift:35:23:35:23 | clean | +| string.swift:34:21:34:21 | tainted | string.swift:35:13:35:13 | tainted | +| string.swift:35:13:35:13 | tainted | string.swift:36:13:36:13 | tainted | +| string.swift:35:23:35:23 | clean | string.swift:38:19:38:19 | clean | +| string.swift:36:13:36:13 | tainted | string.swift:36:23:36:23 | tainted | +| string.swift:36:23:36:23 | tainted | string.swift:39:19:39:19 | tainted | +| string.swift:41:7:41:7 | WriteDef | string.swift:43:13:43:13 | str | +| string.swift:41:13:41:13 | abc | string.swift:41:7:41:7 | WriteDef | +| string.swift:43:13:43:13 | str | string.swift:45:3:45:3 | str | +| string.swift:45:3:45:3 | : &... | string.swift:45:3:45:10 | WriteDef | +| string.swift:45:3:45:3 | str | string.swift:45:3:45:3 | &... | +| string.swift:45:3:45:10 | WriteDef | string.swift:46:13:46:13 | str | +| string.swift:46:13:46:13 | str | string.swift:48:3:48:3 | str | +| string.swift:48:3:48:3 | : &... | string.swift:48:3:48:18 | WriteDef | +| string.swift:48:3:48:3 | str | string.swift:48:3:48:3 | &... | +| string.swift:48:3:48:18 | WriteDef | string.swift:49:13:49:13 | str | +| string.swift:51:7:51:7 | WriteDef | string.swift:53:13:53:13 | str2 | +| string.swift:51:14:51:14 | abc | string.swift:51:7:51:7 | WriteDef | +| string.swift:53:13:53:13 | str2 | string.swift:55:3:55:3 | str2 | +| string.swift:55:3:55:3 | : &... | string.swift:55:3:55:8 | WriteDef | +| string.swift:55:3:55:3 | str2 | string.swift:55:3:55:3 | &... | +| string.swift:55:3:55:8 | WriteDef | string.swift:56:13:56:13 | str2 | +| string.swift:56:13:56:13 | str2 | string.swift:58:3:58:3 | str2 | +| string.swift:58:3:58:3 | : &... | string.swift:58:3:58:8 | WriteDef | +| string.swift:58:3:58:3 | str2 | string.swift:58:3:58:3 | &... | +| string.swift:58:3:58:8 | WriteDef | string.swift:59:13:59:13 | str2 | +| string.swift:59:13:59:13 | str2 | string.swift:69:13:69:13 | str2 | +| string.swift:61:7:61:7 | WriteDef | string.swift:63:13:63:13 | str3 | +| string.swift:61:14:61:14 | abc | string.swift:61:7:61:7 | WriteDef | +| string.swift:63:13:63:13 | str3 | string.swift:65:3:65:3 | str3 | +| string.swift:65:3:65:3 | : &... | string.swift:65:3:65:8 | WriteDef | +| string.swift:65:3:65:3 | str3 | string.swift:65:3:65:3 | &... | +| string.swift:65:3:65:8 | WriteDef | string.swift:66:13:66:13 | str3 | +| string.swift:66:13:66:13 | str3 | string.swift:68:3:68:3 | str3 | +| string.swift:68:3:68:3 | str3 | string.swift:68:3:68:3 | &... | +| string.swift:73:7:73:7 | WriteDef | string.swift:77:20:77:20 | clean | +| string.swift:73:15:73:15 | | string.swift:73:7:73:7 | WriteDef | +| string.swift:74:7:74:7 | WriteDef | string.swift:78:20:78:20 | tainted | +| string.swift:74:17:74:25 | call to source2() | string.swift:74:7:74:7 | WriteDef | +| string.swift:75:7:75:7 | WriteDef | string.swift:79:20:79:20 | taintedInt | +| string.swift:75:20:75:27 | call to source() | string.swift:75:7:75:7 | WriteDef | +| string.swift:77:20:77:20 | clean | string.swift:81:31:81:31 | clean | +| string.swift:78:20:78:20 | tainted | string.swift:82:31:82:31 | tainted | +| string.swift:81:31:81:31 | clean | string.swift:84:13:84:13 | clean | +| string.swift:82:31:82:31 | tainted | string.swift:85:13:85:13 | tainted | +| string.swift:84:13:84:13 | clean | string.swift:87:13:87:13 | clean | +| string.swift:85:13:85:13 | tainted | string.swift:88:13:88:13 | tainted | +| try.swift:8:17:8:23 | call to clean() | try.swift:8:13:8:23 | try ... | +| try.swift:9:17:9:24 | call to source() | try.swift:9:13:9:24 | try ... | +| try.swift:14:17:14:23 | call to clean() | try.swift:14:12:14:23 | try! ... | +| try.swift:15:17:15:24 | call to source() | try.swift:15:12:15:24 | try! ... | +| try.swift:17:13:17:24 | try? ... | try.swift:17:12:17:26 | ...! | +| try.swift:17:18:17:24 | call to clean() | try.swift:17:13:17:24 | try? ... | +| try.swift:18:13:18:25 | try? ... | try.swift:18:12:18:27 | ...! | +| try.swift:18:18:18:25 | call to source() | try.swift:18:13:18:25 | try? ... | +| url.swift:12:6:12:6 | WriteDef | url.swift:14:29:14:29 | clean | +| url.swift:12:14:12:14 | http://example.com/ | url.swift:12:6:12:6 | WriteDef | +| url.swift:13:6:13:6 | WriteDef | url.swift:15:31:15:31 | tainted | +| url.swift:13:16:13:23 | call to source() | url.swift:13:6:13:6 | WriteDef | +| url.swift:14:6:14:6 | WriteDef | url.swift:17:12:17:12 | urlClean | +| url.swift:14:17:14:34 | call to ... | url.swift:14:17:14:35 | ...! | +| url.swift:14:17:14:35 | ...! | url.swift:14:6:14:6 | WriteDef | +| url.swift:14:29:14:29 | clean | url.swift:20:24:20:24 | clean | +| url.swift:15:6:15:6 | WriteDef | url.swift:18:12:18:12 | urlTainted | +| url.swift:15:19:15:38 | call to ... | url.swift:15:19:15:39 | ...! | +| url.swift:15:19:15:39 | ...! | url.swift:15:6:15:6 | WriteDef | +| url.swift:15:31:15:31 | tainted | url.swift:21:24:21:24 | tainted | +| url.swift:17:12:17:12 | urlClean | url.swift:22:43:22:43 | urlClean | +| url.swift:18:12:18:12 | urlTainted | url.swift:23:43:23:43 | urlTainted | +| url.swift:20:12:20:46 | call to ... | url.swift:20:12:20:47 | ...! | +| url.swift:20:24:20:24 | clean | url.swift:22:24:22:24 | clean | +| url.swift:21:12:21:48 | call to ... | url.swift:21:12:21:49 | ...! | +| url.swift:21:24:21:24 | tainted | url.swift:29:25:29:25 | tainted | +| url.swift:22:12:22:51 | call to ... | url.swift:22:12:22:52 | ...! | +| url.swift:22:24:22:24 | clean | url.swift:23:24:23:24 | clean | +| url.swift:23:12:23:53 | call to ... | url.swift:23:12:23:54 | ...! | +| url.swift:23:24:23:24 | clean | url.swift:25:25:25:25 | clean | +| url.swift:25:25:25:25 | clean | url.swift:34:26:34:26 | clean | +| url.swift:29:25:29:25 | tainted | url.swift:38:28:38:28 | tainted | +| url.swift:34:2:34:31 | WriteDef | url.swift:35:12:35:12 | urlClean2 | +| url.swift:34:14:34:31 | call to ... | url.swift:34:2:34:31 | WriteDef | +| url.swift:35:12:35:12 | urlClean2 | url.swift:35:12:35:12 | ...! | +| url.swift:38:2:38:35 | WriteDef | url.swift:39:12:39:12 | urlTainted2 | +| url.swift:38:16:38:35 | call to ... | url.swift:38:2:38:35 | WriteDef | +| url.swift:39:12:39:12 | urlTainted2 | url.swift:39:12:39:12 | ...! | diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/Taint.expected index fea536d78c05..dbfb89540bf2 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.expected @@ -1,20 +1,61 @@ edges -| test.swift:5:11:5:18 | call to source() : | test.swift:7:13:7:13 | "..." | -| test.swift:5:11:5:18 | call to source() : | test.swift:9:13:9:13 | "..." | -| test.swift:5:11:5:18 | call to source() : | test.swift:11:13:11:13 | "..." | -| test.swift:5:11:5:18 | call to source() : | test.swift:16:13:16:13 | "..." | -| test.swift:5:11:5:18 | call to source() : | test.swift:18:13:18:13 | "..." | +| string.swift:5:11:5:18 | call to source() : | string.swift:7:13:7:13 | "..." | +| string.swift:5:11:5:18 | call to source() : | string.swift:9:13:9:13 | "..." | +| string.swift:5:11:5:18 | call to source() : | string.swift:11:13:11:13 | "..." | +| string.swift:5:11:5:18 | call to source() : | string.swift:16:13:16:13 | "..." | +| string.swift:5:11:5:18 | call to source() : | string.swift:18:13:18:13 | "..." | +| string.swift:28:17:28:25 | call to source2() : | string.swift:31:13:31:13 | tainted | +| string.swift:28:17:28:25 | call to source2() : | string.swift:34:13:34:21 | ... call to +(_:_:) ... | +| string.swift:28:17:28:25 | call to source2() : | string.swift:35:13:35:23 | ... call to +(_:_:) ... | +| string.swift:28:17:28:25 | call to source2() : | string.swift:36:13:36:23 | ... call to +(_:_:) ... | +| string.swift:28:17:28:25 | call to source2() : | string.swift:39:13:39:29 | ... call to +(_:_:) ... | +| try.swift:9:17:9:24 | call to source() : | try.swift:9:13:9:24 | try ... | +| try.swift:15:17:15:24 | call to source() : | try.swift:15:12:15:24 | try! ... | +| try.swift:18:18:18:25 | call to source() : | try.swift:18:12:18:27 | ...! | +| url.swift:13:16:13:23 | call to source() : | url.swift:18:12:18:12 | urlTainted | +| url.swift:13:16:13:23 | call to source() : | url.swift:21:12:21:49 | ...! | +| url.swift:13:16:13:23 | call to source() : | url.swift:23:12:23:54 | ...! | +| url.swift:13:16:13:23 | call to source() : | url.swift:39:12:39:12 | ...! | nodes -| test.swift:5:11:5:18 | call to source() : | semmle.label | call to source() : | -| test.swift:7:13:7:13 | "..." | semmle.label | "..." | -| test.swift:9:13:9:13 | "..." | semmle.label | "..." | -| test.swift:11:13:11:13 | "..." | semmle.label | "..." | -| test.swift:16:13:16:13 | "..." | semmle.label | "..." | -| test.swift:18:13:18:13 | "..." | semmle.label | "..." | +| string.swift:5:11:5:18 | call to source() : | semmle.label | call to source() : | +| string.swift:7:13:7:13 | "..." | semmle.label | "..." | +| string.swift:9:13:9:13 | "..." | semmle.label | "..." | +| string.swift:11:13:11:13 | "..." | semmle.label | "..." | +| string.swift:16:13:16:13 | "..." | semmle.label | "..." | +| string.swift:18:13:18:13 | "..." | semmle.label | "..." | +| string.swift:28:17:28:25 | call to source2() : | semmle.label | call to source2() : | +| string.swift:31:13:31:13 | tainted | semmle.label | tainted | +| string.swift:34:13:34:21 | ... call to +(_:_:) ... | semmle.label | ... call to +(_:_:) ... | +| string.swift:35:13:35:23 | ... call to +(_:_:) ... | semmle.label | ... call to +(_:_:) ... | +| string.swift:36:13:36:23 | ... call to +(_:_:) ... | semmle.label | ... call to +(_:_:) ... | +| string.swift:39:13:39:29 | ... call to +(_:_:) ... | semmle.label | ... call to +(_:_:) ... | +| try.swift:9:13:9:24 | try ... | semmle.label | try ... | +| try.swift:9:17:9:24 | call to source() : | semmle.label | call to source() : | +| try.swift:15:12:15:24 | try! ... | semmle.label | try! ... | +| try.swift:15:17:15:24 | call to source() : | semmle.label | call to source() : | +| try.swift:18:12:18:27 | ...! | semmle.label | ...! | +| try.swift:18:18:18:25 | call to source() : | semmle.label | call to source() : | +| url.swift:13:16:13:23 | call to source() : | semmle.label | call to source() : | +| url.swift:18:12:18:12 | urlTainted | semmle.label | urlTainted | +| url.swift:21:12:21:49 | ...! | semmle.label | ...! | +| url.swift:23:12:23:54 | ...! | semmle.label | ...! | +| url.swift:39:12:39:12 | ...! | semmle.label | ...! | subpaths #select -| test.swift:7:13:7:13 | "..." | test.swift:5:11:5:18 | call to source() : | test.swift:7:13:7:13 | "..." | result | -| test.swift:9:13:9:13 | "..." | test.swift:5:11:5:18 | call to source() : | test.swift:9:13:9:13 | "..." | result | -| test.swift:11:13:11:13 | "..." | test.swift:5:11:5:18 | call to source() : | test.swift:11:13:11:13 | "..." | result | -| test.swift:16:13:16:13 | "..." | test.swift:5:11:5:18 | call to source() : | test.swift:16:13:16:13 | "..." | result | -| test.swift:18:13:18:13 | "..." | test.swift:5:11:5:18 | call to source() : | test.swift:18:13:18:13 | "..." | result | +| string.swift:7:13:7:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:7:13:7:13 | "..." | result | +| string.swift:9:13:9:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:9:13:9:13 | "..." | result | +| string.swift:11:13:11:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:11:13:11:13 | "..." | result | +| string.swift:16:13:16:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:16:13:16:13 | "..." | result | +| string.swift:18:13:18:13 | "..." | string.swift:5:11:5:18 | call to source() : | string.swift:18:13:18:13 | "..." | result | +| string.swift:31:13:31:13 | tainted | string.swift:28:17:28:25 | call to source2() : | string.swift:31:13:31:13 | tainted | result | +| string.swift:34:13:34:21 | ... call to +(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:34:13:34:21 | ... call to +(_:_:) ... | result | +| string.swift:35:13:35:23 | ... call to +(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:35:13:35:23 | ... call to +(_:_:) ... | result | +| string.swift:36:13:36:23 | ... call to +(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:36:13:36:23 | ... call to +(_:_:) ... | result | +| string.swift:39:13:39:29 | ... call to +(_:_:) ... | string.swift:28:17:28:25 | call to source2() : | string.swift:39:13:39:29 | ... call to +(_:_:) ... | result | +| try.swift:9:13:9:24 | try ... | try.swift:9:17:9:24 | call to source() : | try.swift:9:13:9:24 | try ... | result | +| try.swift:15:12:15:24 | try! ... | try.swift:15:17:15:24 | call to source() : | try.swift:15:12:15:24 | try! ... | result | +| try.swift:18:12:18:27 | ...! | try.swift:18:18:18:25 | call to source() : | try.swift:18:12:18:27 | ...! | result | +| url.swift:18:12:18:12 | urlTainted | url.swift:13:16:13:23 | call to source() : | url.swift:18:12:18:12 | urlTainted | result | +| url.swift:21:12:21:49 | ...! | url.swift:13:16:13:23 | call to source() : | url.swift:21:12:21:49 | ...! | result | +| url.swift:23:12:23:54 | ...! | url.swift:13:16:13:23 | call to source() : | url.swift:23:12:23:54 | ...! | result | +| url.swift:39:12:39:12 | ...! | url.swift:13:16:13:23 | call to source() : | url.swift:39:12:39:12 | ...! | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/Taint.ql b/swift/ql/test/library-tests/dataflow/taint/Taint.ql index 35836c4cffcc..732976068886 100644 --- a/swift/ql/test/library-tests/dataflow/taint/Taint.ql +++ b/swift/ql/test/library-tests/dataflow/taint/Taint.ql @@ -11,12 +11,12 @@ class TestConfiguration extends TaintTracking::Configuration { TestConfiguration() { this = "TestConfiguration" } override predicate isSource(Node src) { - src.asExpr().(CallExpr).getStaticTarget().getName() = "source()" + src.asExpr().(CallExpr).getStaticTarget().getName().matches("source%") } override predicate isSink(Node sink) { exists(CallExpr sinkCall | - sinkCall.getStaticTarget().getName() = "sink(arg:)" and + sinkCall.getStaticTarget().getName().matches("sink%") and sinkCall.getAnArgument().getExpr() = sink.asExpr() ) } diff --git a/swift/ql/test/library-tests/dataflow/taint/data.swift b/swift/ql/test/library-tests/dataflow/taint/data.swift new file mode 100644 index 000000000000..a1fddd129af1 --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/taint/data.swift @@ -0,0 +1,25 @@ + +class Data +{ + init(_ elements: S) {} +} + +func source() -> String { return "" } +func sink(arg: Data) {} +func sink2(arg: String) {} + +func taintThroughData() { + let dataClean = Data("123456".utf8) + let dataTainted = Data(source().utf8) + let dataTainted2 = Data(dataTainted) + + sink(arg: dataClean) + sink(arg: dataTainted) // tainted [NOT DETECTED] + sink(arg: dataTainted2) // tainted [NOT DETECTED] + + let stringClean = String(data: dataClean, encoding: String.Encoding.utf8) + let stringTainted = String(data: dataTainted, encoding: String.Encoding.utf8) + + sink2(arg: stringClean!) // tainted [NOT DETECTED] + sink2(arg: stringTainted!) // tainted [NOT DETECTED] +} diff --git a/swift/ql/test/library-tests/dataflow/taint/string.swift b/swift/ql/test/library-tests/dataflow/taint/string.swift new file mode 100644 index 000000000000..0855c6d91b04 --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/taint/string.swift @@ -0,0 +1,89 @@ +func source() -> Int { return 0; } +func sink(arg: String) {} + +func taintThroughInterpolatedStrings() { + var x = source() + + sink(arg: "\(x)") // tainted + + sink(arg: "\(x) \(x)") // tainted + + sink(arg: "\(x) \(0) \(x)") // tainted + + var y = 42 + sink(arg: "\(y)") // clean + + sink(arg: "\(x) hello \(y)") // tainted + + sink(arg: "\(y) world \(x)") // tainted + + x = 0 + sink(arg: "\(x)") // clean +} + +func source2() -> String { return ""; } + +func taintThroughStringConcatenation() { + var clean = "abcdef" + var tainted = source2() + + sink(arg: clean) + sink(arg: tainted) // tainted + + sink(arg: clean + clean) + sink(arg: clean + tainted) // tainted + sink(arg: tainted + clean) // tainted + sink(arg: tainted + tainted) // tainted + + sink(arg: ">" + clean + "<") + sink(arg: ">" + tainted + "<") // tainted + + var str = "abc" + + sink(arg: str) + + str += "def" + sink(arg: str) + + str += source2() + sink(arg: str) // tainted [NOT DETECTED] + + var str2 = "abc" + + sink(arg: str2) + + str2.append("def") + sink(arg: str2) + + str2.append(source2()) + sink(arg: str2) // tainted [NOT DETECTED] + + var str3 = "abc" + + sink(arg: str3) + + str3.append(contentsOf: "def") + sink(arg: str3) + + str3.append(contentsOf: source2()) + sink(arg: str2) // tainted [NOT DETECTED] +} + +func taintThroughStringOperations() { + var clean = "" + var tainted = source2() + var taintedInt = source() + + sink(arg: String(clean)) + sink(arg: String(tainted)) // tainted [NOT DETECTED] + sink(arg: String(taintedInt)) // tainted [NOT DETECTED] + + sink(arg: String(repeating: clean, count: 2)) + sink(arg: String(repeating: tainted, count: 2)) // tainted [NOT DETECTED] + + sink(arg: clean.description) + sink(arg: tainted.description) // tainted [NOT DETECTED] + + sink(arg: clean.debugDescription) + sink(arg: tainted.debugDescription) // tainted [NOT DETECTED] +} diff --git a/swift/ql/test/library-tests/dataflow/taint/test.swift b/swift/ql/test/library-tests/dataflow/taint/test.swift deleted file mode 100644 index 36ff201788be..000000000000 --- a/swift/ql/test/library-tests/dataflow/taint/test.swift +++ /dev/null @@ -1,22 +0,0 @@ -func source() -> Int { return 0; } -func sink(arg: String) {} - -func taintThroughInterpolatedStrings() { - var x = source() - - sink(arg: "\(x)") // tainted - - sink(arg: "\(x) \(x)") // tainted - - sink(arg: "\(x) \(0) \(x)") // tainted - - var y = 42 - sink(arg: "\(y)") // clean - - sink(arg: "\(x) hello \(y)") // tainted - - sink(arg: "\(y) world \(x)") // tainted - - x = 0 - sink(arg: "\(x)") // clean -} \ No newline at end of file diff --git a/swift/ql/test/library-tests/dataflow/taint/try.swift b/swift/ql/test/library-tests/dataflow/taint/try.swift new file mode 100644 index 000000000000..80c0bbc07a65 --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/taint/try.swift @@ -0,0 +1,19 @@ +func clean() throws -> String { return ""; } +func source() throws -> String { return ""; } +func sink(arg: String) {} + +func taintThroughTry() { + do + { + sink(arg: try clean()) + sink(arg: try source()) // tainted + } catch { + // ... + } + + sink(arg: try! clean()) + sink(arg: try! source()) // tainted + + sink(arg: (try? clean())!) + sink(arg: (try? source())!) // tainted +} diff --git a/swift/ql/test/library-tests/dataflow/taint/url.swift b/swift/ql/test/library-tests/dataflow/taint/url.swift new file mode 100644 index 000000000000..c7cb5ab12dba --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/taint/url.swift @@ -0,0 +1,40 @@ + +class URL +{ + init?(string: String) {} + init?(string: String, relativeTo: URL?) {} +} + +func source() -> String { return "" } +func sink(arg: URL) {} + +func taintThroughURL() { + let clean = "http://example.com/" + let tainted = source() + let urlClean = URL(string: clean)! + let urlTainted = URL(string: tainted)! + + sink(arg: urlClean) + sink(arg: urlTainted) // tainted + + sink(arg: URL(string: clean, relativeTo: nil)!) + sink(arg: URL(string: tainted, relativeTo: nil)!) // tainted + sink(arg: URL(string: clean, relativeTo: urlClean)!) + sink(arg: URL(string: clean, relativeTo: urlTainted)!) // tainted + + if let x = URL(string: clean) { + sink(arg: x) + } + + if let y = URL(string: tainted) { + sink(arg: y) // tainted [NOT DETECTED] + } + + var urlClean2 : URL! + urlClean2 = URL(string: clean) + sink(arg: urlClean2) + + var urlTainted2 : URL! + urlTainted2 = URL(string: tainted) + sink(arg: urlTainted2) // tainted +}