Merge pull request #10699 from MathiasVP/swift-mad-summaries

This commit is contained in:
Mathias Vorreiter Pedersen
2022-10-06 17:44:35 +01:00
committed by GitHub
15 changed files with 439 additions and 122 deletions

View File

@@ -80,6 +80,7 @@ private import internal.FlowSummaryImplSpecific
private module Frameworks {
private import codeql.swift.frameworks.StandardLibrary.String
private import codeql.swift.frameworks.StandardLibrary.Url
private import codeql.swift.frameworks.StandardLibrary.UrlSession
}
/**
@@ -410,8 +411,10 @@ pragma[nomagic]
private Element interpretElement0(
string namespace, string type, boolean subtypes, string name, string signature
) {
elementSpec(namespace, type, subtypes, name, signature, _) and
namespace = "" and // TODO: Fill out when we properly extract modules.
(
// Non-member functions
exists(AbstractFunctionDecl func |
func.getName() = name and
type = "" and
@@ -421,10 +424,11 @@ private Element interpretElement0(
result = func
)
or
// Member functions
exists(NominalType nomType, IterableDeclContext decl, MethodDecl method |
method.getName() = name and
method = decl.getAMember() and
nomType.getName() = type and
nomType.getFullName() = type and
matchesSignature(method, signature) and
result = method
|
@@ -434,6 +438,20 @@ private Element interpretElement0(
subtypes = false and
getDeclType(decl) = nomType
)
or
signature = "" and
exists(NominalType nomType, IterableDeclContext decl, FieldDecl field |
field.getName() = name and
field = decl.getAMember() and
nomType.getFullName() = type and
result = field
|
subtypes = true and
getDeclType(decl) = nomType.getADerivedType*()
or
subtypes = false and
getDeclType(decl) = nomType
)
)
}
@@ -447,11 +465,18 @@ Element interpretElement(
)
}
/**
* Holds if `c` has a `generated` summary.
*/
predicate hasSummary(SummarizedCallable c, boolean generated) {
summaryElement(c, _, _, _, generated)
private predicate parseField(AccessPathToken c, Content::FieldContent f) {
exists(string fieldRegex, string name |
c.getName() = "Field" and
fieldRegex = "^([^.]+)$" and
name = c.getAnArgument().regexpCapture(fieldRegex, 1) and
f.getField().getName() = name
)
}
/** Holds if the specification component parses as a `Content`. */
predicate parseContent(AccessPathToken component, Content content) {
parseField(component, content)
}
cached

View File

@@ -229,7 +229,9 @@ class SummaryCall extends DataFlowCall, TSummaryCall {
cached
private module Cached {
cached
newtype TDataFlowCallable = TDataFlowFunc(CfgScope scope)
newtype TDataFlowCallable =
TDataFlowFunc(CfgScope scope) or
TSummarizedCallable(FlowSummary::SummarizedCallable c)
/** Gets a viable run-time target for the call `call`. */
cached
@@ -241,6 +243,8 @@ private module Cached {
result = TDataFlowFunc(call.(PropertySetterCall).getAccessorDecl())
or
result = TDataFlowFunc(call.(PropertyObserverCall).getAccessorDecl())
or
result = TSummarizedCallable(call.asCall().getStaticTarget())
}
cached

View File

@@ -64,7 +64,13 @@ private module Cached {
TExprNode(CfgNode n, Expr e) { hasExprNode(n, e) } or
TSsaDefinitionNode(Ssa::Definition def) or
TInoutReturnNode(ParamDecl param) { modifiableParam(param) } or
TSummaryNode(FlowSummary::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) or
TSummaryNode(FlowSummary::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
FlowSummaryImpl::Private::summaryNodeRange(c, state)
} or
TSourceParameterNode(ParamDecl param) or
TSummaryParameterNode(FlowSummary::SummarizedCallable c, ParameterPosition pos) {
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
} or
TExprPostUpdateNode(CfgNode n) {
// Obviously, the base of setters needs a post-update node
n = any(PropertySetterCfgNode setter).getBase()
@@ -93,6 +99,20 @@ private module Cached {
)
}
private SsaDefinitionNode getParameterDefNode(ParamDecl p) {
exists(BasicBlock bb, int i |
bb.getNode(i).getNode().asAstNode() = p and
result.asDefinition().definesAt(_, bb, i)
)
}
/**
* Holds if `nodeFrom` is a parameter node, and `nodeTo` is a corresponding SSA node.
*/
private predicate localFlowSsaParamInput(Node nodeFrom, Node nodeTo) {
nodeTo = getParameterDefNode(nodeFrom.(ParameterNode).getParameter())
}
private predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
exists(Ssa::Definition def |
// Step from assignment RHS to def
@@ -117,6 +137,8 @@ private module Cached {
localFlowSsaInput(nodeFrom, def, nodeTo.asDefinition())
)
or
localFlowSsaParamInput(nodeFrom, nodeTo)
or
// flow through `&` (inout argument)
nodeFrom.asExpr() = nodeTo.asExpr().(InOutExpr).getSubExpr()
or
@@ -125,6 +147,9 @@ private module Cached {
or
// flow through `!`
nodeFrom.asExpr() = nodeTo.asExpr().(ForceValueExpr).getSubExpr()
or
// flow through a flow summary (extension of `SummaryModelCsv`)
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true)
}
/**
@@ -138,7 +163,10 @@ private module Cached {
/** This is the local flow predicate that is exposed. */
cached
predicate localFlowStepImpl(Node nodeFrom, Node nodeTo) { localFlowStepCommon(nodeFrom, nodeTo) }
predicate localFlowStepImpl(Node nodeFrom, Node nodeTo) {
localFlowStepCommon(nodeFrom, nodeTo) or
FlowSummaryImpl::Private::Steps::summaryThroughStepValue(nodeFrom, nodeTo, _)
}
cached
newtype TContentSet = TSingletonContent(Content c)
@@ -181,17 +209,15 @@ predicate nodeIsHidden(Node n) { none() }
private module ParameterNodes {
abstract class ParameterNodeImpl extends NodeImpl {
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { none() }
/** Gets the parameter associated with this node, if any. */
ParamDecl getParameter() { none() }
}
class NormalParameterNode extends ParameterNodeImpl, SsaDefinitionNodeImpl {
class SourceParameterNode extends ParameterNodeImpl, TSourceParameterNode {
ParamDecl param;
NormalParameterNode() {
exists(BasicBlock bb, int i |
super.asDefinition().definesAt(param, bb, i) and
bb.getNode(i).getNode().asAstNode() = param
)
}
SourceParameterNode() { this = TSourceParameterNode(param) }
override Location getLocationImpl() { result = param.getLocation() }
@@ -206,6 +232,26 @@ private module ParameterNodes {
}
override DataFlowCallable getEnclosingCallable() { this.isParameterOf(result, _) }
override ParamDecl getParameter() { result = param }
}
class SummaryParameterNode extends ParameterNodeImpl, TSummaryParameterNode {
FlowSummary::SummarizedCallable sc;
ParameterPosition pos;
SummaryParameterNode() { this = TSummaryParameterNode(sc, pos) }
override predicate isParameterOf(DataFlowCallable c, ParameterPosition p) {
c.getUnderlyingCallable() = sc and
p = pos
}
override Location getLocationImpl() { result = sc.getLocation() }
override string toStringImpl() { result = "[summary param] " + pos + " in " + sc }
override DataFlowCallable getEnclosingCallable() { this.isParameterOf(result, _) }
}
}
@@ -300,6 +346,14 @@ private module ArgumentNodes {
)
}
}
class SummaryArgumentNode extends SummaryNode, ArgumentNode {
SummaryArgumentNode() { FlowSummaryImpl::Private::summaryArgumentNode(_, this, _) }
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
FlowSummaryImpl::Private::summaryArgumentNode(call, this, pos)
}
}
}
import ArgumentNodes
@@ -370,6 +424,12 @@ private module OutNodes {
}
}
class SummaryOutNode extends OutNode, SummaryNode {
override DataFlowCall getCall(ReturnKind kind) {
FlowSummaryImpl::Private::summaryOutNode(result, this, kind)
}
}
class InOutUpdateArgNode extends OutNode, ExprPostUpdateNode {
Argument arg;
@@ -435,6 +495,8 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
node2.(PostUpdateNode).getPreUpdateNode().asExpr() = ref.getBase() and
c.isSingleton(any(Content::FieldContent ct | ct.getField() = ref.getMember()))
)
or
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2)
}
predicate isLValue(Expr e) { any(AssignExpr assign).getDest() = e }
@@ -556,6 +618,9 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
kind = TLambdaCallKind() and
receiver.asExpr() = call.asCall().getExpr().(ApplyExpr).getFunction()
or
kind = TLambdaCallKind() and
receiver = call.(SummaryCall).getReceiver()
}
/** Extra data-flow steps needed for lambda flow analysis. */

View File

@@ -70,7 +70,15 @@ class ExprNode extends Node, TExprNode {
* The value of a parameter at function entry, viewed as a node in a data
* flow graph.
*/
class ParameterNode extends Node, SsaDefinitionNode instanceof ParameterNodeImpl { }
class ParameterNode extends Node instanceof ParameterNodeImpl {
override ControlFlowNode getCfgNode() { result = this.(ParameterNodeImpl).getCfgNode() }
DataFlowCallable getDeclaringFunction() {
result = this.(ParameterNodeImpl).getEnclosingCallable()
}
ParamDecl getParameter() { result = this.(ParameterNodeImpl).getParameter() }
}
/**
*/

View File

@@ -105,12 +105,19 @@ predicate sinkElement(Element e, string input, string kind, boolean generated) {
/** Gets the summary component for specification component `c`, if any. */
bindingset[c]
SummaryComponent interpretComponentSpecific(AccessPathToken c) {
none() // TODO once we have field flow
exists(ContentSet cs, Content content |
cs.isSingleton(content) and
parseContent(c, content) and
result = SummaryComponent::content(cs)
)
}
/** Gets the textual representation of the content in the format used for flow summaries. */
private string getContentSpecificCsv(ContentSet c) {
none() // TODO once we have field flow
private string getContentSpecificCsv(ContentSet cs) {
exists(Content::FieldContent c |
cs.isSingleton(c) and
result = "Field[" + c.getField().getName() + "]"
)
}
/** Gets the textual representation of a summary component in the format used for flow summaries. */
@@ -182,10 +189,17 @@ class InterpretNode extends TInterpretNode {
}
}
/** Provides additional sink specification logic required for attributes. */
predicate interpretOutputSpecific(string c, InterpretNode mid, InterpretNode node) { none() }
predicate interpretOutputSpecific(string c, InterpretNode mid, InterpretNode node) {
// Allow fields to be picked as output nodes.
exists(Node n, AstNode ast |
n = node.asNode() and
ast = mid.asElement()
|
c = "" and
n.asExpr().(MemberRefExpr).getMember() = ast
)
}
/** Provides additional sink specification logic required for attributes. */
predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode n) { none() }
/** Gets the argument position obtained by parsing `X` in `Parameter[X]`. */

View File

@@ -4,6 +4,7 @@ private import TaintTrackingPublic
private import codeql.swift.dataflow.DataFlow
private import codeql.swift.dataflow.Ssa
private import codeql.swift.controlflow.CfgNodes
private import FlowSummaryImpl as FlowSummaryImpl
/**
* Holds if `node` should be a sanitizer in all global taint flow configurations
@@ -48,15 +49,8 @@ private module Cached {
ae.getType().getName() = "String"
)
or
// allow flow through `URL.init`.
exists(CallExpr call, StructDecl c, AbstractFunctionDecl f |
c.getName() = "URL" and
c.getAMember() = f and
f.getName() = ["init(string:)", "init(string:relativeTo:)"] and
call.getStaticTarget() = f and
nodeFrom.asExpr() = call.getAnArgument().getExpr() and
nodeTo.asExpr() = call
)
// flow through a flow summary (extension of `SummaryModelCsv`)
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false)
}
/**

View File

@@ -1,6 +1,7 @@
private import codeql.swift.generated.decl.TypeDecl
private import codeql.swift.generated.type.Type
private import codeql.swift.elements.type.AnyGenericType
private import swift
class TypeDecl extends TypeDeclBase {
override string toString() { result = this.getName() }
@@ -12,4 +13,23 @@ class TypeDecl extends TypeDeclBase {
TypeDecl getDerivedTypeDecl(int i) { result.getBaseTypeDecl(i) = this }
TypeDecl getADerivedTypeDecl() { result = this.getDerivedTypeDecl(_) }
/**
* Gets the full name of this `TypeDecl`. For example in:
* ```swift
* struct A {
* struct B {
* // ...
* }
* }
* ```
* The name and full name of `A` is `A`. The name of `B` is `B`, but the
* full name of `B` is `A.B`.
*/
string getFullName() {
not this.getEnclosingDecl() instanceof TypeDecl and
result = this.getName()
or
result = this.getEnclosingDecl().(TypeDecl).getFullName() + "." + this.getName()
}
}

View File

@@ -5,4 +5,18 @@ class NominalType extends NominalTypeBase {
NominalType getABaseType() { result = this.getDeclaration().(NominalTypeDecl).getABaseType() }
NominalType getADerivedType() { result.getABaseType() = this }
/**
* Gets the full name of this `NominalType`. For example in:
* ```swift
* struct A {
* struct B {
* // ...
* }
* }
* ```
* The name and full name of `A` is `A`. The name of `B` is `B`, but the
* full name of `B` is `A.B`.
*/
string getFullName() { result = this.getDeclaration().(NominalTypeDecl).getFullName() }
}

View File

@@ -1,27 +1,28 @@
import swift
private import codeql.swift.dataflow.FlowSources
private import codeql.swift.dataflow.ExternalFlow
/**
* A model for `URL` members that are sources of remote flow.
*/
class UrlRemoteFlowSource extends RemoteFlowSource {
UrlRemoteFlowSource() {
exists(StructDecl urlClass, ConcreteVarDecl memberDecl |
urlClass.getName() = "URL" and
(
urlClass.getAMember() = memberDecl and
memberDecl.getName() = ["resourceBytes", "lines"]
or
exists(StructDecl asyncBytesClass |
urlClass.getAMember() = asyncBytesClass and
asyncBytesClass.getName() = "AsyncBytes" and
asyncBytesClass.getAMember() = memberDecl and
memberDecl.getName() = "lines"
)
) and
this.asExpr().(MemberRefExpr).getMember() = memberDecl
)
private class UrlRemoteFlowSource extends SourceModelCsv {
override predicate row(string row) {
row =
[
";URL;true;resourceBytes;;;;remote", ";URL;true;lines;;;;remote",
";URL.AsyncBytes;true;lines;;;;remote"
]
}
}
/**
* A model for `URL` members that permit taint flow.
*/
private class UrlSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
[
";URL;true;init(string:);(String);;Argument[0];ReturnValue;taint",
";URL;true;init(string:relativeTo:);(String,URL?);;Argument[0,1];ReturnValue;taint"
]
}
override string getSourceType() { result = "external" }
}

View File

@@ -0,0 +1,8 @@
private import codeql.swift.dataflow.ExternalFlow
private class UrlSessionSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
";URLSession;true;dataTask(with:completionHandler:);;;Argument[0];Argument[1].Parameter[0];taint"
}
}

View File

@@ -10,9 +10,12 @@
| test.swift:15:5:15:5 | Phi | test.swift:15:15:15:15 | t2 |
| test.swift:17:5:17:10 | WriteDef | test.swift:21:15:21:15 | t1 |
| test.swift:17:10:17:10 | 0 | test.swift:17:5:17:10 | WriteDef |
| test.swift:29:18:29:21 | x | test.swift:30:15:30:15 | x |
| test.swift:29:26:29:29 | y | test.swift:31:15:31:15 | y |
| test.swift:42:16:42:19 | b | test.swift:45:8:45:8 | b |
| test.swift:29:18:29:21 | WriteDef | test.swift:30:15:30:15 | x |
| test.swift:29:18:29:21 | x | test.swift:29:18:29:21 | WriteDef |
| test.swift:29:26:29:29 | WriteDef | test.swift:31:15:31:15 | y |
| test.swift:29:26:29:29 | y | test.swift:29:26:29:29 | WriteDef |
| test.swift:42:16:42:19 | WriteDef | test.swift:45:8:45:8 | b |
| test.swift:42:16:42:19 | b | test.swift:42:16:42:19 | WriteDef |
| test.swift:43:9:43:13 | WriteDef | test.swift:46:13:46:13 | t1 |
| test.swift:43:19:43:26 | call to source() | test.swift:43:9:43:13 | WriteDef |
| test.swift:46:9:46:13 | WriteDef | test.swift:50:5:50:5 | Phi |
@@ -28,8 +31,10 @@
| test.swift:61:22:61:23 | &... | test.swift:62:15:62:15 | x |
| test.swift:61:22:61:23 | [post] &... | test.swift:62:15:62:15 | x |
| test.swift:61:23:61:23 | x | test.swift:61:22:61:23 | &... |
| test.swift:65:16:65:28 | arg1 | test.swift:66:21:66:21 | arg1 |
| test.swift:65:33:65:45 | arg2 | test.swift:67:12:67:12 | arg2 |
| test.swift:65:16:65:28 | WriteDef | test.swift:66:21:66:21 | arg1 |
| test.swift:65:16:65:28 | arg1 | test.swift:65:16:65:28 | WriteDef |
| test.swift:65:33:65:45 | WriteDef | test.swift:67:12:67:12 | arg2 |
| test.swift:65:33:65:45 | arg2 | test.swift:65:33:65:45 | WriteDef |
| test.swift:66:9:66:15 | WriteDef | test.swift:68:12:68:12 | temp |
| test.swift:66:21:66:21 | arg1 | test.swift:66:9:66:15 | WriteDef |
| test.swift:67:5:67:12 | WriteDef | test.swift:65:1:70:1 | arg1[return] |
@@ -49,12 +54,14 @@
| test.swift:81:5:81:18 | WriteDef | test.swift:80:1:82:1 | arg[return] |
| test.swift:81:11:81:18 | call to source() | test.swift:81:5:81:18 | WriteDef |
| test.swift:84:1:91:1 | Phi | test.swift:84:1:91:1 | arg[return] |
| test.swift:84:48:84:54 | bool | test.swift:85:8:85:8 | bool |
| test.swift:84:48:84:54 | WriteDef | test.swift:85:8:85:8 | bool |
| test.swift:84:48:84:54 | bool | test.swift:84:48:84:54 | WriteDef |
| test.swift:86:9:86:22 | WriteDef | test.swift:84:1:91:1 | Phi |
| test.swift:86:15:86:22 | call to source() | test.swift:86:9:86:22 | WriteDef |
| test.swift:89:9:89:22 | WriteDef | test.swift:84:1:91:1 | Phi |
| test.swift:89:15:89:22 | call to source() | test.swift:89:9:89:22 | WriteDef |
| test.swift:93:17:93:23 | bool | test.swift:104:50:104:50 | bool |
| test.swift:93:17:93:23 | WriteDef | test.swift:104:50:104:50 | bool |
| test.swift:93:17:93:23 | bool | test.swift:93:17:93:23 | WriteDef |
| test.swift:95:13:95:16 | WriteDef | test.swift:96:19:96:19 | x |
| test.swift:95:22:95:22 | 0 | test.swift:95:13:95:16 | WriteDef |
| test.swift:96:19:96:19 | x | test.swift:97:40:97:40 | x |
@@ -67,45 +74,66 @@
| test.swift:104:40:104:41 | &... | test.swift:105:19:105:19 | x |
| test.swift:104:40:104:41 | [post] &... | test.swift:105:19:105:19 | x |
| test.swift:104:41:104:41 | x | test.swift:104:40:104:41 | &... |
| test.swift:109:9:109:14 | arg | test.swift:110:12:110:12 | arg |
| test.swift:113:14:113:19 | arg | test.swift:114:19:114:19 | arg |
| test.swift:113:24:113:41 | lambda | test.swift:114:12:114:12 | lambda |
| test.swift:109:9:109:14 | WriteDef | test.swift:110:12:110:12 | arg |
| test.swift:109:9:109:14 | arg | test.swift:109:9:109:14 | WriteDef |
| test.swift:113:14:113:19 | WriteDef | test.swift:114:19:114:19 | arg |
| test.swift:113:14:113:19 | arg | test.swift:113:14:113:19 | WriteDef |
| test.swift:113:24:113:41 | WriteDef | test.swift:114:12:114:12 | lambda |
| test.swift:113:24:113:41 | lambda | test.swift:113:24:113:41 | WriteDef |
| test.swift:118:9:118:12 | WriteDef | test.swift:119:31:119:31 | x |
| test.swift:118:18:118:25 | call to source() | test.swift:118:9:118:12 | WriteDef |
| test.swift:119:9:119:12 | WriteDef | test.swift:120:15:120:15 | y |
| test.swift:119:18:119:44 | call to forward(arg:lambda:) | test.swift:119:9:119:12 | WriteDef |
| test.swift:122:9:122:12 | WriteDef | test.swift:126:15:126:15 | z |
| test.swift:122:18:125:6 | call to forward(arg:lambda:) | test.swift:122:9:122:12 | WriteDef |
| test.swift:123:10:123:13 | i | test.swift:124:16:124:16 | i |
| test.swift:123:10:123:13 | WriteDef | test.swift:124:16:124:16 | i |
| test.swift:123:10:123:13 | i | test.swift:123:10:123:13 | WriteDef |
| test.swift:128:9:128:16 | WriteDef | test.swift:132:15:132:15 | clean |
| test.swift:128:22:131:6 | call to forward(arg:lambda:) | test.swift:128:9:128:16 | WriteDef |
| test.swift:141:9:141:9 | WriteDef | test.swift:145:15:145:15 | lambda2 |
| test.swift:141:19:144:5 | { ... } | test.swift:141:9:141:9 | WriteDef |
| test.swift:142:10:142:13 | i | test.swift:143:16:143:16 | i |
| test.swift:142:10:142:13 | WriteDef | test.swift:143:16:143:16 | i |
| test.swift:142:10:142:13 | i | test.swift:142:10:142:13 | WriteDef |
| test.swift:147:9:147:9 | WriteDef | test.swift:151:15:151:15 | lambdaSource |
| test.swift:147:24:150:5 | { ... } | test.swift:147:9:147:9 | WriteDef |
| test.swift:151:15:151:15 | lambdaSource | test.swift:159:16:159:16 | lambdaSource |
| test.swift:153:9:153:9 | WriteDef | test.swift:157:5:157:5 | lambdaSink |
| test.swift:153:22:156:5 | { ... } | test.swift:153:9:153:9 | WriteDef |
| test.swift:154:10:154:13 | i | test.swift:155:19:155:19 | i |
| test.swift:154:10:154:13 | WriteDef | test.swift:155:19:155:19 | i |
| test.swift:154:10:154:13 | i | test.swift:154:10:154:13 | WriteDef |
| test.swift:157:5:157:5 | lambdaSink | test.swift:159:5:159:5 | lambdaSink |
| test.swift:162:7:162:7 | self | test.swift:162:7:162:7 | self[return] |
| test.swift:165:3:165:3 | self | test.swift:166:5:166:5 | self |
| test.swift:162:7:162:7 | WriteDef | test.swift:162:7:162:7 | self[return] |
| test.swift:162:7:162:7 | self | test.swift:162:7:162:7 | WriteDef |
| test.swift:163:7:163:7 | self | test.swift:163:7:163:7 | WriteDef |
| test.swift:163:7:163:7 | self | test.swift:163:7:163:7 | WriteDef |
| test.swift:163:7:163:7 | self | test.swift:163:7:163:7 | WriteDef |
| test.swift:163:7:163:7 | value | test.swift:163:7:163:7 | WriteDef |
| test.swift:165:3:165:3 | WriteDef | test.swift:166:5:166:5 | self |
| test.swift:165:3:165:3 | self | test.swift:165:3:165:3 | WriteDef |
| test.swift:166:5:166:5 | [post] self | test.swift:165:3:167:3 | self[return] |
| test.swift:166:5:166:5 | self | test.swift:165:3:167:3 | self[return] |
| test.swift:169:8:169:8 | self | test.swift:170:5:170:5 | self |
| test.swift:169:12:169:22 | value | test.swift:170:9:170:9 | value |
| test.swift:169:8:169:8 | WriteDef | test.swift:170:5:170:5 | self |
| test.swift:169:8:169:8 | self | test.swift:169:8:169:8 | WriteDef |
| test.swift:169:12:169:22 | WriteDef | test.swift:170:9:170:9 | value |
| test.swift:169:12:169:22 | value | test.swift:169:12:169:22 | WriteDef |
| test.swift:170:5:170:5 | [post] self | test.swift:169:3:171:3 | self[return] |
| test.swift:170:5:170:5 | self | test.swift:169:3:171:3 | self[return] |
| test.swift:173:8:173:8 | self | test.swift:174:12:174:12 | self |
| test.swift:173:8:173:8 | WriteDef | test.swift:174:12:174:12 | self |
| test.swift:173:8:173:8 | self | test.swift:173:8:173:8 | WriteDef |
| test.swift:174:12:174:12 | [post] self | test.swift:173:3:175:3 | self[return] |
| test.swift:174:12:174:12 | self | test.swift:173:3:175:3 | self[return] |
| test.swift:179:7:179:7 | WriteDef | test.swift:180:3:180:3 | a |
| test.swift:179:11:179:13 | call to init() | test.swift:179:7:179:7 | WriteDef |
| test.swift:180:3:180:3 | [post] a | test.swift:181:13:181:13 | a |
| test.swift:180:3:180:3 | a | test.swift:181:13:181:13 | a |
| test.swift:184:7:184:7 | self | test.swift:184:7:184:7 | self[return] |
| test.swift:187:3:187:3 | self | test.swift:188:5:188:5 | self |
| test.swift:184:7:184:7 | WriteDef | test.swift:184:7:184:7 | self[return] |
| test.swift:184:7:184:7 | self | test.swift:184:7:184:7 | WriteDef |
| test.swift:185:7:185:7 | self | test.swift:185:7:185:7 | WriteDef |
| test.swift:185:7:185:7 | self | test.swift:185:7:185:7 | WriteDef |
| test.swift:185:7:185:7 | self | test.swift:185:7:185:7 | WriteDef |
| test.swift:185:7:185:7 | value | test.swift:185:7:185:7 | WriteDef |
| test.swift:187:3:187:3 | WriteDef | test.swift:188:5:188:5 | self |
| test.swift:187:3:187:3 | self | test.swift:187:3:187:3 | WriteDef |
| test.swift:188:5:188:5 | [post] self | test.swift:187:3:189:3 | self[return] |
| test.swift:188:5:188:5 | self | test.swift:187:3:189:3 | self[return] |
| test.swift:193:7:193:7 | WriteDef | test.swift:194:3:194:3 | b |
@@ -128,19 +156,31 @@
| test.swift:217:11:217:13 | call to init() | test.swift:217:7:217:7 | WriteDef |
| test.swift:218:3:218:3 | [post] b | test.swift:219:13:219:13 | b |
| test.swift:218:3:218:3 | b | test.swift:219:13:219:13 | b |
| test.swift:222:7:222:7 | self | test.swift:222:7:222:7 | self[return] |
| test.swift:222:7:222:7 | self | test.swift:222:7:222:7 | self[return] |
| test.swift:224:5:224:5 | self | test.swift:224:5:226:5 | self[return] |
| test.swift:227:5:227:5 | self | test.swift:227:5:229:5 | self[return] |
| test.swift:222:7:222:7 | WriteDef | test.swift:222:7:222:7 | self[return] |
| test.swift:222:7:222:7 | WriteDef | test.swift:222:7:222:7 | self[return] |
| test.swift:222:7:222:7 | self | test.swift:222:7:222:7 | WriteDef |
| test.swift:222:7:222:7 | self | test.swift:222:7:222:7 | WriteDef |
| test.swift:223:7:223:7 | self | test.swift:223:7:223:7 | WriteDef |
| test.swift:224:5:224:5 | WriteDef | test.swift:224:5:226:5 | self[return] |
| test.swift:224:5:224:5 | self | test.swift:224:5:224:5 | WriteDef |
| test.swift:227:5:227:5 | WriteDef | test.swift:227:5:229:5 | self[return] |
| test.swift:227:5:227:5 | self | test.swift:227:5:227:5 | WriteDef |
| test.swift:234:7:234:7 | WriteDef | test.swift:235:13:235:13 | a |
| test.swift:234:11:234:31 | call to init() | test.swift:234:7:234:7 | WriteDef |
| test.swift:235:13:235:13 | [post] a | test.swift:237:3:237:3 | a |
| test.swift:235:13:235:13 | a | test.swift:237:3:237:3 | a |
| test.swift:237:3:237:3 | [post] a | test.swift:238:13:238:13 | a |
| test.swift:237:3:237:3 | a | test.swift:238:13:238:13 | a |
| test.swift:243:9:243:9 | self | test.swift:243:18:243:18 | self |
| test.swift:242:9:242:9 | self | test.swift:242:9:242:9 | WriteDef |
| test.swift:242:9:242:9 | self | test.swift:242:9:242:9 | WriteDef |
| test.swift:242:9:242:9 | self | test.swift:242:9:242:9 | WriteDef |
| test.swift:242:9:242:9 | value | test.swift:242:9:242:9 | WriteDef |
| test.swift:243:9:243:9 | WriteDef | test.swift:243:18:243:18 | self |
| test.swift:243:9:243:9 | self | test.swift:243:9:243:9 | WriteDef |
| test.swift:243:18:243:18 | [post] self | test.swift:243:9:243:42 | self[return] |
| test.swift:243:18:243:18 | self | test.swift:243:9:243:42 | self[return] |
| test.swift:246:5:246:5 | self | test.swift:247:9:247:9 | self |
| test.swift:246:5:246:5 | WriteDef | test.swift:247:9:247:9 | self |
| test.swift:246:5:246:5 | self | test.swift:246:5:246:5 | WriteDef |
| test.swift:247:9:247:9 | [post] self | test.swift:246:5:248:5 | self[return] |
| test.swift:247:9:247:9 | self | test.swift:246:5:248:5 | self[return] |
| test.swift:252:23:252:23 | value | test.swift:252:23:252:23 | WriteDef |

View File

@@ -123,17 +123,3 @@
| string.swift:39:13:39:19 | ... .+(_:_:) ... | string.swift:39:13:39:29 | ... .+(_:_:) ... |
| string.swift:39:19:39:19 | tainted | string.swift:39:13:39:19 | ... .+(_:_:) ... |
| string.swift:39:29:39:29 | < | string.swift:39:13:39:29 | ... .+(_:_:) ... |
| url.swift:14:29:14:29 | clean | url.swift:14:17:14:34 | call to init(string:) |
| url.swift:15:31:15:31 | tainted | url.swift:15:19:15:38 | call to init(string:) |
| url.swift:20:24:20:24 | clean | url.swift:20:12:20:46 | call to init(string:relativeTo:) |
| url.swift:20:43:20:43 | nil | url.swift:20:12:20:46 | call to init(string:relativeTo:) |
| url.swift:21:24:21:24 | tainted | url.swift:21:12:21:48 | call to init(string:relativeTo:) |
| url.swift:21:45:21:45 | nil | url.swift:21:12:21:48 | call to init(string:relativeTo:) |
| url.swift:22:24:22:24 | clean | url.swift:22:12:22:51 | call to init(string:relativeTo:) |
| url.swift:22:43:22:43 | urlClean | url.swift:22:12:22:51 | call to init(string:relativeTo:) |
| url.swift:23:24:23:24 | clean | url.swift:23:12:23:53 | call to init(string:relativeTo:) |
| url.swift:23:43:23:43 | urlTainted | url.swift:23:12:23:53 | call to init(string:relativeTo:) |
| url.swift:25:25:25:25 | clean | url.swift:25:13:25:30 | call to init(string:) |
| url.swift:29:25:29:25 | tainted | url.swift:29:13:29:32 | call to init(string:) |
| url.swift:34:26:34:26 | clean | url.swift:34:14:34:31 | call to init(string:) |
| url.swift:38:28:38:28 | tainted | url.swift:38:16:38:35 | call to init(string:) |

View File

@@ -1,4 +1,5 @@
edges
| file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | url.swift:67:61:67:61 | data : |
| 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 | "..." |
@@ -12,11 +13,46 @@ edges
| 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 | ...! |
| url.swift:8:2:8:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : |
| url.swift:8:8:8:16 | string : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : |
| url.swift:9:2:9:43 | [summary param] 0 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : |
| url.swift:9:2:9:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : |
| url.swift:9:8:9:16 | string : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : |
| url.swift:9:24:9:39 | relativeTo : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : |
| url.swift:26:2:29:55 | [summary param] 0 in dataTask(with:completionHandler:) : | file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : |
| url.swift:27:5:27:15 | url : | file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : |
| url.swift:39:16:39:23 | call to source() : | url.swift:41:31:41:31 | tainted : |
| url.swift:39:16:39:23 | call to source() : | url.swift:47:24:47:24 | tainted : |
| url.swift:39:16:39:23 | call to source() : | url.swift:64:28:64:28 | tainted : |
| url.swift:41:19:41:38 | call to init(string:) : | url.swift:44:12:44:12 | urlTainted |
| url.swift:41:19:41:38 | call to init(string:) : | url.swift:49:43:49:43 | urlTainted : |
| url.swift:41:19:41:38 | call to init(string:) : | url.swift:67:46:67:46 | urlTainted : |
| url.swift:41:31:41:31 | tainted : | url.swift:8:2:8:25 | [summary param] 0 in init(string:) : |
| url.swift:41:31:41:31 | tainted : | url.swift:8:8:8:16 | string : |
| url.swift:41:31:41:31 | tainted : | url.swift:41:19:41:38 | call to init(string:) : |
| url.swift:47:12:47:48 | call to init(string:relativeTo:) : | url.swift:47:12:47:49 | ...! |
| url.swift:47:24:47:24 | tainted : | url.swift:9:2:9:43 | [summary param] 0 in init(string:relativeTo:) : |
| url.swift:47:24:47:24 | tainted : | url.swift:9:8:9:16 | string : |
| url.swift:47:24:47:24 | tainted : | url.swift:47:12:47:48 | call to init(string:relativeTo:) : |
| url.swift:49:12:49:53 | call to init(string:relativeTo:) : | url.swift:49:12:49:54 | ...! |
| url.swift:49:43:49:43 | urlTainted : | url.swift:9:2:9:43 | [summary param] 1 in init(string:relativeTo:) : |
| url.swift:49:43:49:43 | urlTainted : | url.swift:9:24:9:39 | relativeTo : |
| url.swift:49:43:49:43 | urlTainted : | url.swift:49:12:49:53 | call to init(string:relativeTo:) : |
| url.swift:64:16:64:35 | call to init(string:) : | url.swift:65:12:65:12 | ...! |
| url.swift:64:28:64:28 | tainted : | url.swift:8:2:8:25 | [summary param] 0 in init(string:) : |
| url.swift:64:28:64:28 | tainted : | url.swift:8:8:8:16 | string : |
| url.swift:64:28:64:28 | tainted : | url.swift:64:16:64:35 | call to init(string:) : |
| url.swift:67:46:67:46 | urlTainted : | url.swift:26:2:29:55 | [summary param] 0 in dataTask(with:completionHandler:) : |
| url.swift:67:46:67:46 | urlTainted : | url.swift:27:5:27:15 | url : |
| url.swift:67:61:67:61 | data : | url.swift:68:15:68:19 | ...! |
nodes
| file://:0:0:0:0 | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : | semmle.label | [summary] to write: argument 1.parameter 0 in dataTask(with:completionHandler:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | semmle.label | [summary] to write: return (return) in init(string:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | semmle.label | [summary] to write: return (return) in init(string:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : |
| 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 | "..." |
@@ -35,12 +71,39 @@ nodes
| 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 | ...! |
| url.swift:8:2:8:25 | [summary param] 0 in init(string:) : | semmle.label | [summary param] 0 in init(string:) : |
| url.swift:8:8:8:16 | string : | semmle.label | string : |
| url.swift:9:2:9:43 | [summary param] 0 in init(string:relativeTo:) : | semmle.label | [summary param] 0 in init(string:relativeTo:) : |
| url.swift:9:2:9:43 | [summary param] 1 in init(string:relativeTo:) : | semmle.label | [summary param] 1 in init(string:relativeTo:) : |
| url.swift:9:8:9:16 | string : | semmle.label | string : |
| url.swift:9:24:9:39 | relativeTo : | semmle.label | relativeTo : |
| url.swift:26:2:29:55 | [summary param] 0 in dataTask(with:completionHandler:) : | semmle.label | [summary param] 0 in dataTask(with:completionHandler:) : |
| url.swift:27:5:27:15 | url : | semmle.label | url : |
| url.swift:39:16:39:23 | call to source() : | semmle.label | call to source() : |
| url.swift:41:19:41:38 | call to init(string:) : | semmle.label | call to init(string:) : |
| url.swift:41:31:41:31 | tainted : | semmle.label | tainted : |
| url.swift:44:12:44:12 | urlTainted | semmle.label | urlTainted |
| url.swift:47:12:47:48 | call to init(string:relativeTo:) : | semmle.label | call to init(string:relativeTo:) : |
| url.swift:47:12:47:49 | ...! | semmle.label | ...! |
| url.swift:47:24:47:24 | tainted : | semmle.label | tainted : |
| url.swift:49:12:49:53 | call to init(string:relativeTo:) : | semmle.label | call to init(string:relativeTo:) : |
| url.swift:49:12:49:54 | ...! | semmle.label | ...! |
| url.swift:49:43:49:43 | urlTainted : | semmle.label | urlTainted : |
| url.swift:64:16:64:35 | call to init(string:) : | semmle.label | call to init(string:) : |
| url.swift:64:28:64:28 | tainted : | semmle.label | tainted : |
| url.swift:65:12:65:12 | ...! | semmle.label | ...! |
| url.swift:67:46:67:46 | urlTainted : | semmle.label | urlTainted : |
| url.swift:67:61:67:61 | data : | semmle.label | data : |
| url.swift:68:15:68:19 | ...! | semmle.label | ...! |
subpaths
| url.swift:41:31:41:31 | tainted : | url.swift:8:2:8:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | url.swift:41:19:41:38 | call to init(string:) : |
| url.swift:41:31:41:31 | tainted : | url.swift:8:8:8:16 | string : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | url.swift:41:19:41:38 | call to init(string:) : |
| url.swift:47:24:47:24 | tainted : | url.swift:9:2:9:43 | [summary param] 0 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:47:12:47:48 | call to init(string:relativeTo:) : |
| url.swift:47:24:47:24 | tainted : | url.swift:9:8:9:16 | string : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:47:12:47:48 | call to init(string:relativeTo:) : |
| url.swift:49:43:49:43 | urlTainted : | url.swift:9:2:9:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:49:12:49:53 | call to init(string:relativeTo:) : |
| url.swift:49:43:49:43 | urlTainted : | url.swift:9:24:9:39 | relativeTo : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | url.swift:49:12:49:53 | call to init(string:relativeTo:) : |
| url.swift:64:28:64:28 | tainted : | url.swift:8:2:8:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | url.swift:64:16:64:35 | call to init(string:) : |
| url.swift:64:28:64:28 | tainted : | url.swift:8:8:8:16 | string : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | url.swift:64:16:64:35 | call to init(string:) : |
#select
| 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 |
@@ -55,7 +118,8 @@ subpaths
| 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 |
| url.swift:44:12:44:12 | urlTainted | url.swift:39:16:39:23 | call to source() : | url.swift:44:12:44:12 | urlTainted | result |
| url.swift:47:12:47:49 | ...! | url.swift:39:16:39:23 | call to source() : | url.swift:47:12:47:49 | ...! | result |
| url.swift:49:12:49:54 | ...! | url.swift:39:16:39:23 | call to source() : | url.swift:49:12:49:54 | ...! | result |
| url.swift:65:12:65:12 | ...! | url.swift:39:16:39:23 | call to source() : | url.swift:65:12:65:12 | ...! | result |
| url.swift:68:15:68:19 | ...! | url.swift:39:16:39:23 | call to source() : | url.swift:68:15:68:19 | ...! | result |

View File

@@ -1,12 +1,38 @@
class NSObject
{
}
struct URL
{
init?(string: String) {}
init?(string: String, relativeTo: URL?) {}
}
class Data
{
init<S>(_ elements: S) {}
}
class URLResponse : NSObject {}
class URLSessionTask : NSObject { }
class URLSessionDataTask : URLSessionTask { }
class URLSession {
class var shared: URLSession { get { return URLSession() } }
func dataTask(
with url: URL,
completionHandler: (Data?, URLResponse?, Error?) -> Void
) -> URLSessionDataTask { return URLSessionDataTask() }
}
func source() -> String { return "" }
func sink(arg: URL) {}
func sink(data: Data) {}
func sink(string: String) {}
func taintThroughURL() {
let clean = "http://example.com/"
@@ -15,19 +41,19 @@ func taintThroughURL() {
let urlTainted = URL(string: tainted)!
sink(arg: urlClean)
sink(arg: urlTainted) // $ tainted=13
sink(arg: urlTainted) // $ tainted=39
sink(arg: URL(string: clean, relativeTo: nil)!)
sink(arg: URL(string: tainted, relativeTo: nil)!) // $ tainted=13
sink(arg: URL(string: tainted, relativeTo: nil)!) // $ tainted=39
sink(arg: URL(string: clean, relativeTo: urlClean)!)
sink(arg: URL(string: clean, relativeTo: urlTainted)!) // $ tainted=13
sink(arg: URL(string: clean, relativeTo: urlTainted)!) // $ tainted=39
if let x = URL(string: clean) {
sink(arg: x)
}
if let y = URL(string: tainted) {
sink(arg: y) // $ MISSING: tainted=13
sink(arg: y) // $ MISSING: tainted=39
}
var urlClean2 : URL!
@@ -36,5 +62,9 @@ func taintThroughURL() {
var urlTainted2 : URL!
urlTainted2 = URL(string: tainted)
sink(arg: urlTainted2) // $ tainted=13
sink(arg: urlTainted2) // $ tainted=39
let task = URLSession.shared.dataTask(with: urlTainted) { (data, response, error) in
sink(data: data!) // $ tainted=39
}
}

View File

@@ -1,4 +1,8 @@
edges
| UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : |
| UnsafeWebViewFetch.swift:10:8:10:16 | string : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : |
| UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:11:24:11:39 | relativeTo : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:94:10:94:37 | try ... : | UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : |
| UnsafeWebViewFetch.swift:94:10:94:37 | try ... : | UnsafeWebViewFetch.swift:120:25:120:39 | call to getRemoteData() |
| UnsafeWebViewFetch.swift:94:10:94:37 | try ... : | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : |
@@ -11,32 +15,52 @@ edges
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:121:25:121:25 | remoteString |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:124:25:124:51 | ... .+(_:_:) ... |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:127:25:127:25 | "..." |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:131:30:131:30 | remoteString : |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:135:25:135:25 | remoteString |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:137:25:137:25 | remoteString |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:138:47:138:56 | ...! |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:139:25:139:25 | remoteString |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:139:48:139:57 | ...! |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:140:47:140:57 | ...! |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:141:25:141:25 | remoteString |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:141:48:141:58 | ...! |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:153:85:153:94 | ...! |
| UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:154:86:154:95 | ...! |
| UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : | UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL : |
| UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : | UnsafeWebViewFetch.swift:138:47:138:56 | ...! |
| UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : | UnsafeWebViewFetch.swift:139:48:139:57 | ...! |
| UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : | UnsafeWebViewFetch.swift:153:85:153:94 | ...! |
| UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : | UnsafeWebViewFetch.swift:154:86:154:95 | ...! |
| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString : | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in init(string:) : |
| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString : | UnsafeWebViewFetch.swift:10:8:10:16 | string : |
| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString : | UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : |
| UnsafeWebViewFetch.swift:132:19:132:61 | call to init(string:relativeTo:) : | UnsafeWebViewFetch.swift:140:47:140:57 | ...! |
| UnsafeWebViewFetch.swift:132:19:132:61 | call to init(string:relativeTo:) : | UnsafeWebViewFetch.swift:141:48:141:58 | ...! |
| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL : | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL : | UnsafeWebViewFetch.swift:11:24:11:39 | relativeTo : |
| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL : | UnsafeWebViewFetch.swift:132:19:132:61 | call to init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:168:25:168:25 | remoteString |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:171:25:171:51 | ... .+(_:_:) ... |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:174:25:174:25 | "..." |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:178:30:178:30 | remoteString : |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:182:25:182:25 | remoteString |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:184:25:184:25 | remoteString |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:185:47:185:56 | ...! |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:186:25:186:25 | remoteString |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:186:48:186:57 | ...! |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:187:47:187:57 | ...! |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:188:25:188:25 | remoteString |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:188:48:188:58 | ...! |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:200:90:200:99 | ...! |
| UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() : | UnsafeWebViewFetch.swift:201:91:201:100 | ...! |
| UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : | UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL : |
| UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : | UnsafeWebViewFetch.swift:185:47:185:56 | ...! |
| UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : | UnsafeWebViewFetch.swift:186:48:186:57 | ...! |
| UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : | UnsafeWebViewFetch.swift:200:90:200:99 | ...! |
| UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : | UnsafeWebViewFetch.swift:201:91:201:100 | ...! |
| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString : | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in init(string:) : |
| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString : | UnsafeWebViewFetch.swift:10:8:10:16 | string : |
| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString : | UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : |
| UnsafeWebViewFetch.swift:179:19:179:61 | call to init(string:relativeTo:) : | UnsafeWebViewFetch.swift:187:47:187:57 | ...! |
| UnsafeWebViewFetch.swift:179:19:179:61 | call to init(string:relativeTo:) : | UnsafeWebViewFetch.swift:188:48:188:58 | ...! |
| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL : | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL : | UnsafeWebViewFetch.swift:11:24:11:39 | relativeTo : |
| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL : | UnsafeWebViewFetch.swift:179:19:179:61 | call to init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() : | UnsafeWebViewFetch.swift:210:25:210:25 | htmlData |
| UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() : | UnsafeWebViewFetch.swift:211:25:211:25 | htmlData |
nodes
| UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in init(string:) : | semmle.label | [summary param] 0 in init(string:) : |
| UnsafeWebViewFetch.swift:10:8:10:16 | string : | semmle.label | string : |
| UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : | semmle.label | [summary param] 1 in init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:11:24:11:39 | relativeTo : | semmle.label | relativeTo : |
| UnsafeWebViewFetch.swift:94:10:94:37 | try ... : | semmle.label | try ... : |
| UnsafeWebViewFetch.swift:94:14:94:37 | call to init(contentsOf:) : | semmle.label | call to init(contentsOf:) : |
| UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | semmle.label | try! ... |
@@ -50,6 +74,10 @@ nodes
| UnsafeWebViewFetch.swift:121:25:121:25 | remoteString | semmle.label | remoteString |
| UnsafeWebViewFetch.swift:124:25:124:51 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| UnsafeWebViewFetch.swift:127:25:127:25 | "..." | semmle.label | "..." |
| UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : | semmle.label | call to init(string:) : |
| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString : | semmle.label | remoteString : |
| UnsafeWebViewFetch.swift:132:19:132:61 | call to init(string:relativeTo:) : | semmle.label | call to init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL : | semmle.label | remoteURL : |
| UnsafeWebViewFetch.swift:135:25:135:25 | remoteString | semmle.label | remoteString |
| UnsafeWebViewFetch.swift:137:25:137:25 | remoteString | semmle.label | remoteString |
| UnsafeWebViewFetch.swift:138:47:138:56 | ...! | semmle.label | ...! |
@@ -65,6 +93,10 @@ nodes
| UnsafeWebViewFetch.swift:168:25:168:25 | remoteString | semmle.label | remoteString |
| UnsafeWebViewFetch.swift:171:25:171:51 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
| UnsafeWebViewFetch.swift:174:25:174:25 | "..." | semmle.label | "..." |
| UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : | semmle.label | call to init(string:) : |
| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString : | semmle.label | remoteString : |
| UnsafeWebViewFetch.swift:179:19:179:61 | call to init(string:relativeTo:) : | semmle.label | call to init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL : | semmle.label | remoteURL : |
| UnsafeWebViewFetch.swift:182:25:182:25 | remoteString | semmle.label | remoteString |
| UnsafeWebViewFetch.swift:184:25:184:25 | remoteString | semmle.label | remoteString |
| UnsafeWebViewFetch.swift:185:47:185:56 | ...! | semmle.label | ...! |
@@ -78,7 +110,19 @@ nodes
| UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() : | semmle.label | call to getRemoteData() : |
| UnsafeWebViewFetch.swift:210:25:210:25 | htmlData | semmle.label | htmlData |
| UnsafeWebViewFetch.swift:211:25:211:25 | htmlData | semmle.label | htmlData |
| file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | semmle.label | [summary] to write: return (return) in init(string:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | semmle.label | [summary] to write: return (return) in init(string:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : |
| file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | semmle.label | [summary] to write: return (return) in init(string:relativeTo:) : |
subpaths
| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString : | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : |
| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString : | UnsafeWebViewFetch.swift:10:8:10:16 | string : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | UnsafeWebViewFetch.swift:131:18:131:42 | call to init(string:) : |
| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL : | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | UnsafeWebViewFetch.swift:132:19:132:61 | call to init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL : | UnsafeWebViewFetch.swift:11:24:11:39 | relativeTo : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | UnsafeWebViewFetch.swift:132:19:132:61 | call to init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString : | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : |
| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString : | UnsafeWebViewFetch.swift:10:8:10:16 | string : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:) : | UnsafeWebViewFetch.swift:178:18:178:42 | call to init(string:) : |
| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL : | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in init(string:relativeTo:) : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | UnsafeWebViewFetch.swift:179:19:179:61 | call to init(string:relativeTo:) : |
| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL : | UnsafeWebViewFetch.swift:11:24:11:39 | relativeTo : | file://:0:0:0:0 | [summary] to write: return (return) in init(string:relativeTo:) : | UnsafeWebViewFetch.swift:179:19:179:61 | call to init(string:relativeTo:) : |
#select
| UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | UnsafeWebViewFetch.swift:103:30:103:84 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | Tainted data is used in a WebView fetch without restricting the base URL. |
| UnsafeWebViewFetch.swift:106:25:106:25 | data | UnsafeWebViewFetch.swift:105:18:105:72 | call to init(contentsOf:) : | UnsafeWebViewFetch.swift:106:25:106:25 | data | Tainted data is used in a WebView fetch without restricting the base URL. |