From 397ff848989271bfe56c5979412fa1716b7d05a8 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 6 Mar 2019 11:41:12 +0100 Subject: [PATCH 1/7] C#: Cache `Ssa::ExplicitDefinition::getADefinition()` --- csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll index 9a5cc6e82fac..e6a43f063841 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll @@ -67,6 +67,14 @@ module Ssa { ) ) } + + cached + AssignableDefinition getADefinition(ExplicitDefinition def) { + exists(TrackedVar tv, AssignableDefinition ad | def = TSsaExplicitDef(tv, ad, _, _) | + result = ad or + result = getASameOutRefDefAfter(tv, ad) + ) + } } import Cached @@ -587,8 +595,7 @@ module Ssa { * (when `k` is `SsaDef()`). */ private predicate ssaRef(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) { - exists(ReadKind rk | - variableRead(bb, i, v, _, rk) | + exists(ReadKind rk | variableRead(bb, i, v, _, rk) | not rk instanceof RefReadBeforeWrite and k = SsaRead() ) @@ -2248,8 +2255,7 @@ module Ssa { * where there may be more than one underlying definition. */ AssignableDefinition getADefinition() { - result = ad or - result = getASameOutRefDefAfter(tv, ad) + result = getADefinition(this) } /** From 738d1117f2216010aae89842fd78488ac618ab87 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 1 Mar 2019 11:53:40 +0100 Subject: [PATCH 2/7] C#: Avoid recomputing `flowThroughCallableLibraryOutRef()` between queries --- csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll | 9 +++------ .../ql/src/semmle/code/csharp/dataflow/TaintTracking.qll | 5 +++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index 52058c6f52e5..d1fcb05a5269 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -996,6 +996,8 @@ module DataFlow { or Internal::flowOutOfDelegateLibraryCall(nodeFrom, nodeTo, true) or + flowThroughCallableLibraryOutRef(_, nodeFrom, nodeTo, true) + or localFlowStepCil(nodeFrom, nodeTo) } @@ -1079,17 +1081,12 @@ module DataFlow { (isSuccessor = true or isSuccessor = false) } - predicate localFlowStepNoConfig(Node pred, Node succ) { - localFlowStep(pred, succ) or - flowThroughCallableLibraryOutRef(_, pred, succ, true) - } - /** * Holds if data may flow in one local step from `pred` to `succ`. */ bindingset[config] predicate localFlowStep(Node pred, Node succ, Configuration config) { - localFlowStepNoConfig(pred, succ) or + localFlowStep(pred, succ) or config.isAdditionalFlowStep(pred, succ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/TaintTracking.qll b/csharp/ql/src/semmle/code/csharp/dataflow/TaintTracking.qll index 8964506921ef..5085adf3a446 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/TaintTracking.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/TaintTracking.qll @@ -81,8 +81,7 @@ module TaintTracking { final override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { isAdditionalTaintStep(pred, succ) or - localAdditionalTaintStep(pred, succ) or - DataFlow::Internal::flowThroughCallableLibraryOutRef(_, pred, succ, false) + localAdditionalTaintStep(pred, succ) } final override predicate isAdditionalFlowStepIntoCall( @@ -257,6 +256,8 @@ module TaintTracking { or access.(PropertyRead).getQualifier() = nodeFrom.asExpr() ) + or + DataFlow::Internal::flowThroughCallableLibraryOutRef(_, nodeFrom, nodeTo, false) } } import Cached From e6630cda6b3fc61fbc0d0ff0ee5ad26a03bf8197 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 5 Mar 2019 20:50:46 +0100 Subject: [PATCH 3/7] C#: Use explicit recursion in data flow predicate --- csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index d1fcb05a5269..1cc8f77531df 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -1811,7 +1811,12 @@ module DataFlow { private predicate flowThroughCallable1Scope(OutNode out, Expr e) { flowThroughCallable0(_, out, _) and - e = out.asExpr().(Expr).getAChildExpr*() + e = out.asExpr() + or + exists(Expr mid | + flowThroughCallable1Scope(out, mid) | + e = mid.getAChildExpr() + ) } pragma[nomagic] From e6f7632d4c622a6d231268afc839c5fcac5df751 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 1 Mar 2019 15:50:10 +0100 Subject: [PATCH 4/7] C#: Introduce data flow return nodes Before this change, ``` flowOutOfCallableStep(CallNode call, ReturnNode ret, OutNode out, CallContext cc) ``` would compute all combinations of call sites `call` and returned expressions `ret` up front. Now, we instead introduce explicit return nodes, so each callable has exactly one return node (as well as one for each `out`/`ref` parameter). There is then local flow from a returned expression to the relevant return node, and `flowOutOfCallableStep()` computes combinations of call sites and return nodes. Not only does this result in better performance, it also makes `flowOutOfCallableStep()` symmetric to `flowIntoCallableStep()`, where each argument is mapped to a parameter, and not to all reads of that parameter. --- .../semmle/code/csharp/dataflow/DataFlow.qll | 281 ++++++++++-------- .../code/csharp/dataflow/DelegateDataFlow.qll | 14 +- .../code/csharp/dataflow/TaintTracking.qll | 17 +- .../csharp7/LocalTaintFlow.expected | 33 ++ .../csharp7/TaintReaches.expected | 2 + .../dataflow/global/DataFlowPath.expected | 28 +- .../global/TaintTrackingPath.expected | 32 +- .../dataflow/local/DataFlowStep.expected | 16 + .../dataflow/local/TaintTrackingStep.expected | 16 + .../CWE-338/InsecureRandomness.expected | 17 +- .../CWE-838/InappropriateEncoding.expected | 4 +- 11 files changed, 297 insertions(+), 163 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index 1cc8f77531df..70fcfb2af1ee 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -246,17 +246,6 @@ module DataFlow { none() } - /** - * INTERNAL: Do not use. - * - * Holds if the additional flow step from `ret` to `out` out of the call - * `call` must be taken into account in the analysis, but only in call - * context `cc`. - */ - predicate isAdditionalFlowStepOutOfCall(Node call, Node ret, Node out, CallContext cc) { - none() - } - /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -503,8 +492,10 @@ module DataFlow { /** * Holds if this argument occurs at position `pos` in call `call`. */ - predicate isArgumentOf(CallNode call, int pos, Configuration config) { - exists(ExplicitParameterNode p | flowIntoCallableStep(call, this, p, _, config) | + private predicate isArgumentOf(CallNode call, int pos, Configuration config) { + exists(ExplicitParameterNode p | + Pruning::flowIntoCallableStepCand(call, this, p, _, config) + | pos = p.getParameter().getPosition() ) } @@ -518,7 +509,6 @@ module DataFlow { ) } - bindingset[config] override ExplicitArgumentContext getContext(Configuration config) { result.getCallContext() = this.getArgumentCallContext(config) } @@ -591,18 +581,47 @@ module DataFlow { abstract private class ReturnNode extends Node { } /** - * A data flow node that represents an expression returned explicitly by a callable. - * Either an argument of `return`/`yield return` or an expression assigned to an - * `out`/`ref` parameter. + * A data flow node that represents an expression returned by a callable, + * using an ordinary `return` or a method expression. */ - private class ExplicitReturnNode extends ReturnNode, ExprNode { - ExplicitReturnNode() { - exists(DotNet::Callable c, DotNet::Expr e | e = this.getExpr() | - c.canReturn(e) or - c.(Callable).canYieldReturn(e) or - callableReturnsOutOrRef(c, _, e) - ) - } + class NormalReturnNode extends ReturnNode, TNormalReturnNode { + override Type getType() { result = this.getEnclosingCallable().getReturnType() } + + override DotNet::Callable getEnclosingCallable() { this = TNormalReturnNode(result) } + + override string toString() { result = "return" } + + override Location getLocation() { result = this.getEnclosingCallable().getLocation() } + } + + /** + * A data flow node that represents an expression returned by a callable, + * using `yield return`. + */ + class YieldReturnNode extends ReturnNode, TYieldReturnNode { + override Type getType() { result = this.getEnclosingCallable().getReturnType() } + + override Callable getEnclosingCallable() { this = TYieldReturnNode(result) } + + override string toString() { result = "yield return" } + + override Location getLocation() { result = this.getEnclosingCallable().getLocation() } + } + + /** + * A data flow node that represents an expression returned by a callable, + * using an `out`/`ref` parameter. + */ + private class OutRefReturnNode extends ReturnNode, TOutRefReturnNode { + Parameter getParameter() { this = TOutRefReturnNode(result) } + + override Type getType() { result = this.getParameter().getType() } + + override Callable getEnclosingCallable() { result = this.getParameter().getCallable() } + + override string toString() { result = "return (out/ref)" } + + override Location getLocation() { result = this.getParameter().getLocation() } } /** @@ -998,6 +1017,12 @@ module DataFlow { or flowThroughCallableLibraryOutRef(_, nodeFrom, nodeTo, true) or + exists(DotNet::Callable c | c.canReturn(nodeFrom.asExpr()) | nodeTo = TNormalReturnNode(c)) + or + exists(Parameter p | callableReturnsOutOrRef(_, p, nodeFrom.asExpr()) | + nodeTo = TOutRefReturnNode(p) + ) + or localFlowStepCil(nodeFrom, nodeTo) } @@ -1100,7 +1125,10 @@ module DataFlow { config.isSource(node) or jumpStep(_, node) or node instanceof ParameterNode or - node instanceof OutNode + node instanceof OutNode or + node instanceof NormalReturnNode or + node instanceof YieldReturnNode or + node instanceof OutRefReturnNode ) } @@ -1111,9 +1139,18 @@ module DataFlow { predicate localFlowExit(Node node, Configuration config) { Pruning::nodeCand(node, config) and ( - jumpStep(node, _) or - node instanceof ArgumentNode or - node instanceof ReturnNode or + jumpStep(node, _) + or + node instanceof ArgumentNode + or + node instanceof ReturnNode + or + exists(ReturnNode rn | localFlowStep(node, rn, config) | + rn instanceof NormalReturnNode or + rn instanceof YieldReturnNode or + rn instanceof OutRefReturnNode + ) + or config.isSink(node) ) } @@ -1175,9 +1212,7 @@ module DataFlow { flowIntoCallableStep(_, arg, node, _, config) ) or - exists(Node mid | nodeCandFwd1(mid, config) | - flowOutOfCallableStep(_, mid, node, _, config) - ) + exists(Node mid | nodeCandFwd1(mid, config) | flowOutOfCallableStep(mid, _, node, _)) ) } @@ -1198,7 +1233,7 @@ module DataFlow { flowIntoCallableStep(_, node, p, _, config) ) or - exists(Node mid | nodeCand1(mid, config) | flowOutOfCallableStep(_, node, mid, _, config)) + exists(Node mid | nodeCand1(mid, config) | flowOutOfCallableStep(node, _, mid, _)) ) } @@ -1258,12 +1293,15 @@ module DataFlow { flowIntoCallableStep(call, arg, p, _, config) } - pragma[noinline] + // noopt is need to force scan of `nodeCand1()` followed by join on + // `flowOutOfCallableStep()`, instead of the other way around + pragma[noopt] private predicate flowOutOfCallableStepCand1( CallNode call, ReturnNode ret, OutNode out, Configuration config ) { - nodeCand1(out, config) and - flowOutOfCallableStep(call, ret, out, _, config) + nodeCand1(ret, _) and + nodeCand1(ret, config) and + flowOutOfCallableStep(ret, call, out, _) } /** @@ -1313,12 +1351,15 @@ module DataFlow { flowIntoCallableStep(_, arg, p, _, config) } - pragma[noinline] + // noopt is need to force scan of `nodeCandFwd2()` followed by join on + // `flowOutOfCallableStep()`, instead of the other way around + pragma[noopt] private predicate flowOutOfCallableStepCandFwd2( - CallNode call, ReturnNode ret, OutNode out, CallContext cc, Configuration config + ReturnNode ret, OutNode out, Configuration config ) { + nodeCandFwd2(ret, _, _) and nodeCandFwd2(ret, _, config) and - flowOutOfCallableStep(call, ret, out, cc, config) + flowOutOfCallableStep(ret, _, out, _) } /** @@ -1346,7 +1387,7 @@ module DataFlow { ) or exists(OutNode out | nodeCand2(out, _, config) | - flowOutOfCallableStepCandFwd2(_, node, out, _, config) and + flowOutOfCallableStepCandFwd2(node, out, config) and isReturned = true ) or @@ -1360,7 +1401,27 @@ module DataFlow { * Holds if `node` is part of a path from a source to a sink in the * configuration `config`, taking simple call contexts into consideration. */ + pragma[noinline] predicate nodeCand(Node node, Configuration config) { nodeCand2(node, _, config) } + + pragma[noinline] + predicate flowIntoCallableStepCand( + CallNode call, ArgumentNode arg, ParameterNode p, CallContext cc, Configuration config + ) { + nodeCand(p, config) and + flowIntoCallableStep(call, arg, p, cc, config) + } + + // noopt is need to force scan of `nodeCand()` followed by join on + // `flowOutOfCallableStep()`, instead of the other way around + pragma[noopt] + predicate flowOutOfCallableStepCand( + CallNode call, ReturnNode ret, OutNode out, CallContext cc, Configuration config + ) { + nodeCand(ret, _) and + nodeCand(ret, config) and + flowOutOfCallableStep(ret, call, out, cc) + } } // A workaround to avoid eager joining on configurations @@ -1387,7 +1448,10 @@ module DataFlow { exists(Ssa::ExplicitDefinition def | def.isCapturedVariableDefinitionFlowIn(_, c) | v = def.getSourceVariable().getAssignable() ) - } + } or + TNormalReturnNode(DotNet::Callable c) { c.canReturn(_) } or + TYieldReturnNode(Callable c) { c.canYieldReturn(_) } or + TOutRefReturnNode(Parameter p) { callableReturnsOutOrRef(_, p, _) } /** * Holds if `pred` can flow to `succ`, by jumping from one callable to @@ -1453,23 +1517,15 @@ module DataFlow { * account. */ cached - predicate flowOutOfCallableStepNoConfig( - CallNode call, ReturnNode ret, OutNode out, CallContext cc - ) { - flowOutOfCallableExplicitStep(call, ret, out, cc) - or - flowOutOfCallableCapturedVarStep(call, ret, out) and - cc instanceof EmptyCallContext - } - - private predicate flowOutOfCallableExplicitStep( - CallNode call, ReturnNode ret, OutNode out, CallContext cc - ) { - flowOutOfCallableNonDelegateCall(call.asExpr(), ret.asExpr(), out) and + predicate flowOutOfCallableStep(ReturnNode ret, CallNode call, OutNode out, CallContext cc) { + flowOutOfCallableNonDelegateCall(call.asExpr(), ret, out) and cc instanceof EmptyCallContext or - flowOutOfCallableDelegateCall(call, ret.asExpr(), cc) and + flowOutOfCallableDelegateCall(call, ret, cc) and out = call + or + flowOutOfCallableCapturedVarStep(call, ret, out) and + cc instanceof EmptyCallContext } /** @@ -1496,9 +1552,9 @@ module DataFlow { Pruning::nodeCand(arg, _) } or TReturnContext(CallNode call, DotNet::Callable callable) { - exists(ReturnNode ret, Configuration config | Pruning::nodeCand(ret, config) | + exists(ReturnNode ret | callable = ret.getEnclosingCallable() and - flowOutOfCallableStep(call, ret, _, _, config) + Pruning::flowOutOfCallableStepCand(call, ret, _, _, _) ) } @@ -1516,8 +1572,8 @@ module DataFlow { * Holds if flow out of a callable is allowed to go via the call * `call` in this context. */ - bindingset[call, config] - predicate flowOutAllowedToCall(DotNet::Expr call, Configuration config) { + bindingset[call] + predicate flowOutAllowedToCall(DotNet::Expr call) { // This context poses no restriction this instanceof NoContext or // Data in this context is from a call, so flow back out must be through @@ -1529,8 +1585,8 @@ module DataFlow { // call context, in which case flow further out must respect that call // context this = any(ReturnContext rc | - not exists(rc.getARequiredContext(config)) or - rc.getARequiredContext(config).(ArgumentCallContext).isArgument(call, _) + not exists(rc.getARequiredContext()) or + rc.getARequiredContext().(ArgumentCallContext).isArgument(call, _) ) } } @@ -1595,22 +1651,15 @@ module DataFlow { * Gets a call context required for the flow out to the data described by this * context to be possible. */ - ArgumentCallContext getARequiredContext(Configuration config) { - result = getARequiredContext0(call, callable, config) + ArgumentCallContext getARequiredContext() { + exists(ReturnNode ret | Pruning::flowOutOfCallableStepCand(call, ret, _, result, _) | + callable = ret.getEnclosingCallable() + ) } override string toString() { result = call.toString() } } - pragma[noinline] - private ArgumentCallContext getARequiredContext0( - CallNode call, DotNet::Callable callable, Configuration config - ) { - exists(ReturnNode ret | flowOutOfCallableStep(call, ret, _, result, config) | - callable = ret.getEnclosingCallable() - ) - } - newtype TFlowGraphNode = TFlowGraphNode0(Node node, Context ctx, Configuration config) { // A source @@ -1700,16 +1749,15 @@ module DataFlow { pragma[noinline] private predicate flowIntoCallable0(FlowGraphNode mid, ArgumentNode arg, ParameterNode p) { - exists(Context outerctx, CallContext cc, Configuration config | - config = mid.getConfiguration() and - flowIntoCallableStep(_, arg, p, cc, config) and + exists(Context outerctx, CallContext cc | + Pruning::flowIntoCallableStepCand(_, arg, p, cc, mid.getConfiguration()) and arg = mid.getNode() and outerctx = mid.getContext() | cc instanceof EmptyCallContext or exists(DotNet::Expr call | cc.(ArgumentCallContext).isArgument(call, _) | - outerctx.flowOutAllowedToCall(call, config) + outerctx.flowOutAllowedToCall(call) ) ) } @@ -1728,7 +1776,7 @@ module DataFlow { private predicate flowOutOfCallable0( FlowGraphNode mid, CallNode call, OutNode out, DotNet::Callable callable, Context innerctx ) { - flowOutOfCallableStep(call, mid.getNode(), out, _, mid.getConfiguration()) and + Pruning::flowOutOfCallableStepCand(call, mid.getNode(), out, _, mid.getConfiguration()) and innerctx = mid.getContext() and not innerctx instanceof ArgumentContext and callable = mid.getEnclosingCallable() @@ -1744,7 +1792,7 @@ module DataFlow { flowOutOfCallable0(mid, call, out, callable, innerctx) and outerctx = TReturnContext(call, callable) | - innerctx.flowOutAllowedToCall(call.getCall(), mid.getConfiguration()) + innerctx.flowOutAllowedToCall(call.getCall()) ) } @@ -1755,7 +1803,7 @@ module DataFlow { exists(int i | innerctx.getCallContext() = call.getCallContext(i) | mid.getNode() = ret and mid.getContext() = innerctx and - mid.getEnclosingCallable().getParameter(i) = p.getParameter() + mid.getEnclosingCallable() = p.getParameter().getCallable() ) } @@ -1771,13 +1819,14 @@ module DataFlow { /** Holds if data may flow from `p` to a a node `out` returned by the callable. */ private predicate paramFlowsThrough( - CallNode call, ParameterNode p, OutNode out, ArgumentContext innerctx, CallContext cc + CallNode call, ParameterNode p, OutNode out, ArgumentContext innerctx, CallContext cc, + Configuration config ) { exists(FlowGraphNode mid, ReturnNode ret | paramFlowsThroughExplicit(call, p, innerctx, mid, ret) or paramFlowsThroughImplicit(call, p, innerctx, mid, ret) | - flowOutOfCallableStep(call, ret, out, cc, mid.getConfiguration()) + Pruning::flowOutOfCallableStepCand(call, ret, out, cc, config) ) } @@ -1789,7 +1838,7 @@ module DataFlow { private predicate flowThroughCallable0(FlowGraphNode mid, OutNode out, Context ctx) { exists(CallNode call, ParameterNode p, ArgumentContext innerctx, CallContext cc | flowIntoCallable(mid, p, innerctx) and - paramFlowsThrough(call, p, out, innerctx, cc) + paramFlowsThrough(call, p, out, innerctx, cc, mid.getConfiguration()) | // Data in `mid` is from a call, so that call must match the required call (if any), // and the context after flow through `call` must be recovered @@ -1813,10 +1862,7 @@ module DataFlow { flowThroughCallable0(_, out, _) and e = out.asExpr() or - exists(Expr mid | - flowThroughCallable1Scope(out, mid) | - e = mid.getAChildExpr() - ) + exists(Expr mid | flowThroughCallable1Scope(out, mid) | e = mid.getAChildExpr()) } pragma[nomagic] @@ -1970,21 +2016,6 @@ module DataFlow { config.isAdditionalFlowStepIntoCall(call, arg, p.getParameter(), cc) } - /** - * Holds if `ret` is an expression returned by a callable to which the call - * `call` resolves, and `out` is the corresponding output (either `call` - * itself or an `out`/`ref` argument). - * - * Additional steps specified by the configuration are taken into account. - */ - bindingset[config] - predicate flowOutOfCallableStep( - CallNode call, ReturnNode ret, OutNode out, CallContext cc, Configuration config - ) { - flowOutOfCallableStepNoConfig(call, ret, out, cc) or - config.isAdditionalFlowStepOutOfCall(call, ret, out, cc) - } - /** * Holds if `arg` is an argument of the non-delegate call `call`, * which resolves to a callable with corresponding parameter `p`. @@ -2053,25 +2084,35 @@ module DataFlow { p = result.getParameter(i) } + pragma[noinline] + private predicate flowOutOfCallableNonDelegateCall0(ReturnNode ret, DotNet::Callable c) { + c = ret.(NormalReturnNode).getEnclosingCallable() + or + c = ret.(YieldReturnNode).getEnclosingCallable() + } + + pragma[noinline] + private predicate flowOutOfCallableNonDelegateCall1(NonDelegateCall call, ReturnNode ret) { + flowOutOfCallableNonDelegateCall0(ret, call.getARuntimeTarget()) + } + /** * Holds if `ret` is an expression returned by a callable to * which the non-delegate call `call` resolves, and `out` is the * corresponding output (either `call` itself or first uses of * a relevant `out`/`ref` argument). */ - predicate flowOutOfCallableNonDelegateCall(NonDelegateCall call, DotNet::Expr ret, OutNode out) { - exists(DotNet::Callable callable | callable = call.getARuntimeTarget() | - // ordinary return value - callable.canReturn(ret) and - call = out.asExpr() - or - // return via out/ref parameter - exists(Parameter outRef, AssignableDefinitions::OutRefDefinition def | - callableReturnsOutOrRef(callable.getSourceDeclaration(), outRef.getSourceDeclaration(), - ret) and - def = out.(SsaDefinitionNode).getDefinition().(Ssa::ExplicitDefinition).getADefinition() and - def.getTargetAccess() = call.(Call).getArgumentForParameter(outRef) - ) + predicate flowOutOfCallableNonDelegateCall(NonDelegateCall call, ReturnNode ret, OutNode out) { + // (yield) return value + flowOutOfCallableNonDelegateCall1(call, ret) and + call = out.asExpr() + or + // return via out/ref parameter + exists(Parameter p, AssignableDefinitions::OutRefDefinition def | + p.getSourceDeclaration() = ret.(OutRefReturnNode).getParameter() + | + def = out.(SsaDefinitionNode).getDefinition().(Ssa::ExplicitDefinition).getADefinition() and + def.getTargetAccess() = call.(Call).getArgumentForParameter(p) ) } @@ -2079,8 +2120,10 @@ module DataFlow { * Holds if `ret` is an expression returned by a callable to * which the delegate call `call` resolves. */ - private predicate flowOutOfCallableDelegateCall(CallNode call, Expr ret, CallContext cc) { - exists(Callable target | target.getSourceDeclaration().canReturn(ret) | + private predicate flowOutOfCallableDelegateCall( + CallNode call, NormalReturnNode ret, CallContext cc + ) { + exists(Callable target | ret.getEnclosingCallable() = target.getSourceDeclaration() | target = call.asExpr().(DelegateCall).getARuntimeTarget(cc) or target = call.(ImplicitDelegateCallNode).getArgument().getARuntimeTarget(cc) ) @@ -2090,11 +2133,11 @@ module DataFlow { * Holds if callable `c` can return `e` as an `out`/`ref` value * for parameter `outRef`. */ - predicate callableReturnsOutOrRef(Callable c, Parameter outRef, Expr e) { + predicate callableReturnsOutOrRef(Callable c, Parameter p, Expr e) { exists(Ssa::ExplicitDefinition def | def.getADefinition().getSource() = e and - def.isLiveOutRefParameterDefinition(outRef) and - outRef = c.getAParameter() + def.isLiveOutRefParameterDefinition(p) and + p = c.getAParameter() ) } } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DelegateDataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DelegateDataFlow.qll index a8da58aba3ff..3b6a225b551f 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DelegateDataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DelegateDataFlow.qll @@ -205,14 +205,14 @@ private predicate flowsFrom( exists(DataFlow::Node mid | flowsFrom(sink, mid, _, lastCall) and isReturned = true and - flowOutOfCallableNonDelegateCall(_, node.asExpr(), mid) + flowOutOfCallableNonDelegateCall(_, node, mid) ) or // Flow out of a callable (delegate call). exists(DataFlow::ExprNode mid | flowsFrom(sink, mid, _, _) and isReturned = true and - flowOutOfDelegateCall(mid.getExpr(), node.asExpr(), lastCall) + flowOutOfDelegateCall(mid.getExpr(), node, lastCall) ) } @@ -230,7 +230,7 @@ private CallContext getLastCall(CallContext prevLastCall, Expr call, int i) { result = prevLastCall } -// Predicate folding to get proper join-order +pragma[noinline] private predicate flowIntoDelegateCall(DelegateCall dc, Callable c, Expr e, int i) { exists(DelegateFlowSource dfs, DelegateCallExpr dce | // the call context is irrelevant because the delegate call @@ -242,11 +242,13 @@ private predicate flowIntoDelegateCall(DelegateCall dc, Callable c, Expr e, int ) } -// Predicate folding to get proper join-order -private predicate flowOutOfDelegateCall(DelegateCall dc, Expr e, CallContext lastCall) { +pragma[noinline] +private predicate flowOutOfDelegateCall( + DelegateCall dc, DataFlow::Internal::NormalReturnNode ret, CallContext lastCall +) { exists(DelegateFlowSource dfs, DelegateCallExpr dce, Callable c | flowsFrom(dce, dfs, _, lastCall) and - c.canReturn(e) and + ret.getEnclosingCallable() = c and c = dfs.getCallable() and dc = dce.getDelegateCall() ) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/TaintTracking.qll b/csharp/ql/src/semmle/code/csharp/dataflow/TaintTracking.qll index 5085adf3a446..d7c41bc3ac34 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/TaintTracking.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/TaintTracking.qll @@ -90,17 +90,6 @@ module TaintTracking { DataFlow::Internal::flowIntoCallableLibraryCall(_, arg, call, p, false, cc) } - final override predicate isAdditionalFlowStepOutOfCall( - DataFlow::Node call, DataFlow::Node ret, DataFlow::Node out, CallContext::CallContext cc - ) { - exists(DispatchCall dc, Callable callable | canYieldReturn(callable, ret.asExpr()) | - dc.getCall() = call.asExpr() and - call = out and - callable = dc.getADynamicTarget() and - cc instanceof CallContext::EmptyCallContext - ) - } - /** * Holds if taint may flow from `source` to `sink` for this configuration. */ @@ -112,8 +101,6 @@ module TaintTracking { /** INTERNAL: Do not use. */ module Internal { - predicate canYieldReturn(Callable c, Expr e) { c.getSourceDeclaration().canYieldReturn(e) } - private CIL::DataFlowNode asCilDataFlowNode(DataFlow::Node node) { result = node.asParameter() or result = node.asExpr() @@ -258,6 +245,10 @@ module TaintTracking { ) or DataFlow::Internal::flowThroughCallableLibraryOutRef(_, nodeFrom, nodeTo, false) + or + exists(Callable c | c.canYieldReturn(nodeFrom.asExpr()) | + c = nodeTo.(DataFlow::Internal::YieldReturnNode).getEnclosingCallable() + ) } } import Cached diff --git a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected index b72be6ff5e83..ff611fa08501 100644 --- a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected +++ b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected @@ -1,17 +1,27 @@ +| CSharp7.cs:17:18:17:22 | access to field field | CSharp7.cs:17:9:17:11 | return | +| CSharp7.cs:18:14:18:14 | 5 | CSharp7.cs:18:14:18:14 | return | +| CSharp7.cs:21:16:21:20 | call to method Foo | CSharp7.cs:21:9:21:11 | return | | CSharp7.cs:22:9:22:11 | value | CSharp7.cs:22:24:22:28 | access to parameter value | +| CSharp7.cs:22:16:22:28 | ... = ... | CSharp7.cs:22:9:22:11 | return | +| CSharp7.cs:25:39:25:43 | call to method Foo | CSharp7.cs:25:5:25:27 | return | +| CSharp7.cs:26:35:26:39 | call to method Foo | CSharp7.cs:26:6:26:28 | return | | CSharp7.cs:31:19:31:19 | i | CSharp7.cs:33:16:33:16 | access to parameter i | | CSharp7.cs:33:16:33:16 | access to parameter i | CSharp7.cs:33:16:33:20 | ... > ... | | CSharp7.cs:33:16:33:16 | access to parameter i | CSharp7.cs:33:24:33:24 | access to parameter i | | CSharp7.cs:33:16:33:20 | ... > ... | CSharp7.cs:33:16:33:59 | ... ? ... : ... | +| CSharp7.cs:33:16:33:59 | ... ? ... : ... | CSharp7.cs:31:9:31:13 | return | | CSharp7.cs:33:24:33:24 | access to parameter i | CSharp7.cs:33:16:33:59 | ... ? ... : ... | | CSharp7.cs:33:28:33:59 | throw ... | CSharp7.cs:33:16:33:59 | ... ? ... : ... | +| CSharp7.cs:41:13:41:21 | "tainted" | CSharp7.cs:39:23:39:23 | return (out/ref) | | CSharp7.cs:41:13:41:21 | "tainted" | CSharp7.cs:41:9:41:21 | SSA def(x) | | CSharp7.cs:44:19:44:19 | x | CSharp7.cs:46:13:46:13 | access to parameter x | +| CSharp7.cs:46:13:46:13 | access to parameter x | CSharp7.cs:44:33:44:33 | return (out/ref) | | CSharp7.cs:46:13:46:13 | access to parameter x | CSharp7.cs:46:9:46:13 | SSA def(y) | | CSharp7.cs:51:22:51:23 | SSA def(t1) | CSharp7.cs:53:18:53:19 | access to local variable t1 | | CSharp7.cs:52:19:52:20 | SSA def(t2) | CSharp7.cs:56:14:56:15 | access to local variable t2 | | CSharp7.cs:54:15:54:16 | SSA def(t1) | CSharp7.cs:55:14:55:15 | access to local variable t1 | | CSharp7.cs:57:30:57:31 | SSA def(t4) | CSharp7.cs:58:18:58:19 | access to local variable t4 | +| CSharp7.cs:66:16:66:21 | (..., ...) | CSharp7.cs:64:16:64:16 | return | | CSharp7.cs:66:17:66:17 | 1 | CSharp7.cs:66:16:66:21 | (..., ...) | | CSharp7.cs:66:20:66:20 | 2 | CSharp7.cs:66:16:66:21 | (..., ...) | | CSharp7.cs:72:13:72:19 | SSA def(z) | CSharp7.cs:75:16:75:16 | access to local variable z | @@ -39,6 +49,7 @@ | CSharp7.cs:79:27:79:27 | access to local variable x | CSharp7.cs:79:22:79:28 | (..., ...) | | CSharp7.cs:82:21:82:21 | x | CSharp7.cs:84:20:84:20 | access to parameter x | | CSharp7.cs:84:16:84:24 | (..., ...) | CSharp7.cs:84:16:84:26 | access to field a | +| CSharp7.cs:84:16:84:26 | access to field a | CSharp7.cs:82:12:82:12 | return | | CSharp7.cs:84:20:84:20 | access to parameter x | CSharp7.cs:84:16:84:24 | (..., ...) | | CSharp7.cs:84:23:84:23 | 2 | CSharp7.cs:84:16:84:24 | (..., ...) | | CSharp7.cs:89:13:89:34 | SSA def(t1) | CSharp7.cs:90:28:90:29 | access to local variable t1 | @@ -86,30 +97,47 @@ | CSharp7.cs:123:28:123:36 | "DefUse3" | CSharp7.cs:123:22:123:36 | ... = ... | | CSharp7.cs:131:20:131:20 | x | CSharp7.cs:131:32:131:32 | access to parameter x | | CSharp7.cs:131:32:131:32 | access to parameter x | CSharp7.cs:131:32:131:36 | ... + ... | +| CSharp7.cs:131:32:131:36 | ... + ... | CSharp7.cs:131:9:131:39 | return | | CSharp7.cs:131:36:131:36 | 1 | CSharp7.cs:131:32:131:36 | ... + ... | | CSharp7.cs:133:22:133:22 | t | CSharp7.cs:133:39:133:39 | access to parameter t | +| CSharp7.cs:133:39:133:39 | access to parameter t | CSharp7.cs:133:9:133:42 | return | +| CSharp7.cs:137:21:137:21 | 2 | CSharp7.cs:137:9:137:22 | return | | CSharp7.cs:139:29:139:29 | x | CSharp7.cs:139:34:139:34 | access to parameter x | | CSharp7.cs:139:34:139:34 | access to parameter x | CSharp7.cs:139:34:139:38 | ... + ... | +| CSharp7.cs:139:34:139:38 | ... + ... | CSharp7.cs:139:29:139:38 | return | | CSharp7.cs:139:38:139:38 | 1 | CSharp7.cs:139:34:139:38 | ... + ... | | CSharp7.cs:141:20:141:20 | x | CSharp7.cs:141:26:141:26 | access to parameter x | | CSharp7.cs:141:26:141:26 | access to parameter x | CSharp7.cs:141:26:141:30 | ... > ... | | CSharp7.cs:141:26:141:26 | access to parameter x | CSharp7.cs:141:41:141:41 | access to parameter x | | CSharp7.cs:141:26:141:30 | ... > ... | CSharp7.cs:141:26:141:50 | ... ? ... : ... | +| CSharp7.cs:141:26:141:50 | ... ? ... : ... | CSharp7.cs:141:9:141:51 | return | | CSharp7.cs:141:34:141:34 | 1 | CSharp7.cs:141:34:141:46 | ... + ... | | CSharp7.cs:141:34:141:46 | ... + ... | CSharp7.cs:141:26:141:50 | ... ? ... : ... | | CSharp7.cs:141:38:141:46 | call to local function f7 | CSharp7.cs:141:34:141:46 | ... + ... | | CSharp7.cs:141:50:141:50 | 0 | CSharp7.cs:141:26:141:50 | ... ? ... : ... | | CSharp7.cs:143:20:143:20 | x | CSharp7.cs:143:29:143:29 | access to parameter x | +| CSharp7.cs:143:26:143:30 | call to local function f6 | CSharp7.cs:143:9:143:31 | return | | CSharp7.cs:147:24:147:24 | x | CSharp7.cs:147:33:147:33 | access to parameter x | +| CSharp7.cs:147:30:147:34 | call to local function f7 | CSharp7.cs:147:13:147:35 | return | +| CSharp7.cs:148:20:148:24 | call to local function f9 | CSharp7.cs:145:9:149:9 | return | +| CSharp7.cs:152:25:152:25 | 0 | CSharp7.cs:152:13:152:26 | return | +| CSharp7.cs:155:16:155:20 | call to local function f1 | CSharp7.cs:129:9:129:12 | return | +| CSharp7.cs:160:23:160:23 | 1 | CSharp7.cs:160:9:160:24 | return | | CSharp7.cs:161:18:161:18 | t | CSharp7.cs:161:24:161:24 | access to parameter t | +| CSharp7.cs:161:24:161:24 | access to parameter t | CSharp7.cs:161:9:161:25 | return | | CSharp7.cs:163:26:163:26 | u | CSharp7.cs:167:22:167:22 | access to parameter u | +| CSharp7.cs:165:25:165:30 | call to local function f | CSharp7.cs:165:13:165:31 | return | +| CSharp7.cs:167:20:167:23 | call to local function g | CSharp7.cs:163:9:168:9 | return | | CSharp7.cs:176:16:176:30 | SSA def(src) | CSharp7.cs:181:23:181:25 | access to local variable src | | CSharp7.cs:176:22:176:30 | "tainted" | CSharp7.cs:176:16:176:30 | SSA def(src) | | CSharp7.cs:177:25:177:25 | s | CSharp7.cs:177:33:177:33 | access to parameter s | | CSharp7.cs:177:31:177:34 | call to local function g | CSharp7.cs:177:31:177:39 | ... + ... | +| CSharp7.cs:177:31:177:39 | ... + ... | CSharp7.cs:177:9:177:40 | return | | CSharp7.cs:177:38:177:39 | "" | CSharp7.cs:177:31:177:39 | ... + ... | | CSharp7.cs:178:25:178:25 | s | CSharp7.cs:178:31:178:31 | access to parameter s | +| CSharp7.cs:178:31:178:31 | access to parameter s | CSharp7.cs:178:9:178:32 | return | | CSharp7.cs:179:25:179:25 | s | CSharp7.cs:179:37:179:37 | access to parameter s | +| CSharp7.cs:179:37:179:37 | access to parameter s | CSharp7.cs:179:9:179:40 | return | | CSharp7.cs:181:23:181:25 | access to local variable src | CSharp7.cs:182:23:182:25 | access to local variable src | | CSharp7.cs:182:23:182:25 | access to local variable src | CSharp7.cs:183:23:183:25 | access to local variable src | | CSharp7.cs:191:13:191:18 | SSA def(v1) | CSharp7.cs:192:26:192:27 | access to local variable v1 | @@ -128,7 +156,11 @@ | CSharp7.cs:199:33:199:34 | access to local variable r1 | CSharp7.cs:200:16:200:17 | access to local variable r1 | | CSharp7.cs:203:24:203:24 | p | CSharp7.cs:206:20:206:20 | access to parameter p | | CSharp7.cs:205:28:205:28 | q | CSharp7.cs:205:44:205:44 | access to parameter q | +| CSharp7.cs:205:40:205:44 | ref ... | CSharp7.cs:205:9:205:47 | return | +| CSharp7.cs:206:16:206:20 | ref ... | CSharp7.cs:203:13:203:14 | return | +| CSharp7.cs:216:13:216:17 | false | CSharp7.cs:214:30:214:30 | return (out/ref) | | CSharp7.cs:216:13:216:17 | false | CSharp7.cs:216:9:216:17 | SSA def(x) | +| CSharp7.cs:217:16:217:23 | (..., ...) | CSharp7.cs:214:19:214:19 | return | | CSharp7.cs:217:17:217:17 | 0 | CSharp7.cs:217:16:217:23 | (..., ...) | | CSharp7.cs:217:20:217:22 | 0 | CSharp7.cs:217:16:217:23 | (..., ...) | | CSharp7.cs:233:16:233:23 | SSA def(o) | CSharp7.cs:234:13:234:13 | access to local variable o | @@ -179,6 +211,7 @@ | CSharp7.cs:284:20:284:62 | call to method Select | CSharp7.cs:284:13:284:62 | SSA def(list) | | CSharp7.cs:284:32:284:35 | item | CSharp7.cs:284:41:284:44 | access to parameter item | | CSharp7.cs:284:32:284:61 | [implicit call] (...) => ... | CSharp7.cs:284:20:284:62 | call to method Select | +| CSharp7.cs:284:40:284:61 | (..., ...) | CSharp7.cs:284:32:284:61 | return | | CSharp7.cs:284:41:284:44 | access to parameter item | CSharp7.cs:284:51:284:54 | access to parameter item | | CSharp7.cs:284:41:284:48 | access to property Key | CSharp7.cs:284:40:284:61 | (..., ...) | | CSharp7.cs:284:51:284:54 | access to parameter item | CSharp7.cs:284:51:284:60 | access to property Value | diff --git a/csharp/ql/test/library-tests/csharp7/TaintReaches.expected b/csharp/ql/test/library-tests/csharp7/TaintReaches.expected index d5d232488ad0..4ffde6f4d13b 100644 --- a/csharp/ql/test/library-tests/csharp7/TaintReaches.expected +++ b/csharp/ql/test/library-tests/csharp7/TaintReaches.expected @@ -1,3 +1,4 @@ +| CSharp7.cs:41:13:41:21 | "tainted" | CSharp7.cs:39:23:39:23 | return (out/ref) | | CSharp7.cs:41:13:41:21 | "tainted" | CSharp7.cs:41:9:41:21 | SSA def(x) | | CSharp7.cs:79:23:79:24 | "" | CSharp7.cs:79:22:79:28 | (..., ...) | | CSharp7.cs:89:19:89:27 | "tainted" | CSharp7.cs:89:13:89:34 | SSA def(t1) | @@ -29,6 +30,7 @@ | CSharp7.cs:176:22:176:30 | "tainted" | CSharp7.cs:181:23:181:25 | access to local variable src | | CSharp7.cs:176:22:176:30 | "tainted" | CSharp7.cs:182:23:182:25 | access to local variable src | | CSharp7.cs:176:22:176:30 | "tainted" | CSharp7.cs:183:23:183:25 | access to local variable src | +| CSharp7.cs:177:38:177:39 | "" | CSharp7.cs:177:9:177:40 | return | | CSharp7.cs:177:38:177:39 | "" | CSharp7.cs:177:31:177:39 | ... + ... | | CSharp7.cs:236:33:236:36 | "int " | CSharp7.cs:236:31:236:41 | $"..." | | CSharp7.cs:240:33:240:39 | "string " | CSharp7.cs:240:31:240:44 | $"..." | diff --git a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected index e4a65d2dd2c4..da4987a5fe59 100644 --- a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected @@ -137,7 +137,8 @@ edges | GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | GlobalDataFlow.cs:153:15:153:19 | access to local variable sink7 | | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | GlobalDataFlow.cs:156:15:156:19 | access to local variable sink8 | | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | GlobalDataFlow.cs:160:15:160:20 | access to local variable sink23 | -| GlobalDataFlow.cs:175:35:175:48 | "taint source" | GlobalDataFlow.cs:176:21:176:26 | delegate call | +| GlobalDataFlow.cs:175:29:175:48 | return | GlobalDataFlow.cs:176:21:176:26 | delegate call | +| GlobalDataFlow.cs:175:35:175:48 | "taint source" | GlobalDataFlow.cs:175:29:175:48 | return | | GlobalDataFlow.cs:176:21:176:26 | delegate call | GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | GlobalDataFlow.cs:186:15:186:20 | access to local variable sink10 | | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | GlobalDataFlow.cs:194:15:194:20 | access to local variable sink19 | @@ -153,10 +154,13 @@ edges | GlobalDataFlow.cs:251:26:251:35 | sinkParam5 | GlobalDataFlow.cs:253:15:253:24 | access to parameter sinkParam5 | | GlobalDataFlow.cs:256:26:256:35 | sinkParam6 | GlobalDataFlow.cs:258:15:258:24 | access to parameter sinkParam6 | | GlobalDataFlow.cs:261:26:261:35 | sinkParam7 | GlobalDataFlow.cs:263:15:263:24 | access to parameter sinkParam7 | -| GlobalDataFlow.cs:313:16:313:29 | "taint source" | GlobalDataFlow.cs:149:21:149:25 | call to method Out | -| GlobalDataFlow.cs:313:16:313:29 | "taint source" | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | -| GlobalDataFlow.cs:318:13:318:26 | "taint source" | GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | -| GlobalDataFlow.cs:323:13:323:26 | "taint source" | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | +| GlobalDataFlow.cs:311:12:311:14 | return | GlobalDataFlow.cs:149:21:149:25 | call to method Out | +| GlobalDataFlow.cs:311:12:311:14 | return | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | +| GlobalDataFlow.cs:313:16:313:29 | "taint source" | GlobalDataFlow.cs:311:12:311:14 | return | +| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | +| GlobalDataFlow.cs:318:13:318:26 | "taint source" | GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | +| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | +| GlobalDataFlow.cs:323:13:323:26 | "taint source" | GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | | GlobalDataFlow.cs:354:41:354:41 | x | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | | GlobalDataFlow.cs:354:41:354:41 | x | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | GlobalDataFlow.cs:53:15:53:15 | x | @@ -167,11 +171,12 @@ edges | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:56:37:56:37 | x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:251:26:251:35 | sinkParam5 | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:256:26:256:35 | sinkParam6 | +| GlobalDataFlow.cs:373:19:373:30 | return | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | +| GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:373:19:373:30 | return | | GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | -| GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | -| GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | | GlobalDataFlow.cs:399:9:399:11 | value | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | -| GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | +| GlobalDataFlow.cs:410:9:410:11 | return | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | +| GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:410:9:410:11 | return | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | @@ -270,6 +275,7 @@ nodes | GlobalDataFlow.cs:156:15:156:19 | access to local variable sink8 | | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | | GlobalDataFlow.cs:160:15:160:20 | access to local variable sink23 | +| GlobalDataFlow.cs:175:29:175:48 | return | | GlobalDataFlow.cs:175:35:175:48 | "taint source" | | GlobalDataFlow.cs:176:21:176:26 | delegate call | | GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | @@ -295,8 +301,11 @@ nodes | GlobalDataFlow.cs:258:15:258:24 | access to parameter sinkParam6 | | GlobalDataFlow.cs:261:26:261:35 | sinkParam7 | | GlobalDataFlow.cs:263:15:263:24 | access to parameter sinkParam7 | +| GlobalDataFlow.cs:311:12:311:14 | return | | GlobalDataFlow.cs:313:16:313:29 | "taint source" | +| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | | GlobalDataFlow.cs:318:13:318:26 | "taint source" | +| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | | GlobalDataFlow.cs:323:13:323:26 | "taint source" | | GlobalDataFlow.cs:354:41:354:41 | x | | GlobalDataFlow.cs:354:41:354:41 | x | @@ -308,11 +317,12 @@ nodes | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | +| GlobalDataFlow.cs:373:19:373:30 | return | | GlobalDataFlow.cs:373:39:373:45 | tainted | | GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | -| GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | | GlobalDataFlow.cs:399:9:399:11 | value | | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | +| GlobalDataFlow.cs:410:9:410:11 | return | | GlobalDataFlow.cs:410:22:410:35 | "taint source" | | Splitting.cs:3:28:3:34 | tainted | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | diff --git a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected index d46b2550bffa..2f4168a0f638 100644 --- a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected @@ -161,7 +161,8 @@ edges | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | GlobalDataFlow.cs:156:15:156:19 | access to local variable sink8 | | GlobalDataFlow.cs:157:22:157:31 | call to method OutYield | GlobalDataFlow.cs:158:15:158:20 | access to local variable sink12 | | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | GlobalDataFlow.cs:160:15:160:20 | access to local variable sink23 | -| GlobalDataFlow.cs:175:35:175:48 | "taint source" | GlobalDataFlow.cs:176:21:176:26 | delegate call | +| GlobalDataFlow.cs:175:29:175:48 | return | GlobalDataFlow.cs:176:21:176:26 | delegate call | +| GlobalDataFlow.cs:175:35:175:48 | "taint source" | GlobalDataFlow.cs:175:29:175:48 | return | | GlobalDataFlow.cs:176:21:176:26 | delegate call | GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | GlobalDataFlow.cs:186:15:186:20 | access to local variable sink10 | | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | GlobalDataFlow.cs:194:15:194:20 | access to local variable sink19 | @@ -195,11 +196,15 @@ edges | GlobalDataFlow.cs:287:31:287:40 | sinkParam8 | GlobalDataFlow.cs:289:15:289:24 | access to parameter sinkParam8 | | GlobalDataFlow.cs:293:32:293:41 | sinkParam9 | GlobalDataFlow.cs:295:15:295:24 | access to parameter sinkParam9 | | GlobalDataFlow.cs:299:32:299:42 | sinkParam11 | GlobalDataFlow.cs:301:15:301:25 | access to parameter sinkParam11 | -| GlobalDataFlow.cs:313:16:313:29 | "taint source" | GlobalDataFlow.cs:149:21:149:25 | call to method Out | -| GlobalDataFlow.cs:313:16:313:29 | "taint source" | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | -| GlobalDataFlow.cs:318:13:318:26 | "taint source" | GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | -| GlobalDataFlow.cs:323:13:323:26 | "taint source" | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | -| GlobalDataFlow.cs:329:22:329:35 | "taint source" | GlobalDataFlow.cs:157:22:157:31 | call to method OutYield | +| GlobalDataFlow.cs:311:12:311:14 | return | GlobalDataFlow.cs:149:21:149:25 | call to method Out | +| GlobalDataFlow.cs:311:12:311:14 | return | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | +| GlobalDataFlow.cs:313:16:313:29 | "taint source" | GlobalDataFlow.cs:311:12:311:14 | return | +| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | +| GlobalDataFlow.cs:318:13:318:26 | "taint source" | GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | +| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | +| GlobalDataFlow.cs:323:13:323:26 | "taint source" | GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | +| GlobalDataFlow.cs:326:25:326:32 | yield return | GlobalDataFlow.cs:157:22:157:31 | call to method OutYield | +| GlobalDataFlow.cs:329:22:329:35 | "taint source" | GlobalDataFlow.cs:326:25:326:32 | yield return | | GlobalDataFlow.cs:354:41:354:41 | x | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | | GlobalDataFlow.cs:354:41:354:41 | x | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | GlobalDataFlow.cs:53:15:53:15 | x | @@ -210,11 +215,12 @@ edges | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:56:37:56:37 | x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:251:26:251:35 | sinkParam5 | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:256:26:256:35 | sinkParam6 | +| GlobalDataFlow.cs:373:19:373:30 | return | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | +| GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:373:19:373:30 | return | | GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | -| GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | -| GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | | GlobalDataFlow.cs:399:9:399:11 | value | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | -| GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | +| GlobalDataFlow.cs:410:9:410:11 | return | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | +| GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:410:9:410:11 | return | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | @@ -337,6 +343,7 @@ nodes | GlobalDataFlow.cs:158:15:158:20 | access to local variable sink12 | | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | | GlobalDataFlow.cs:160:15:160:20 | access to local variable sink23 | +| GlobalDataFlow.cs:175:29:175:48 | return | | GlobalDataFlow.cs:175:35:175:48 | "taint source" | | GlobalDataFlow.cs:176:21:176:26 | delegate call | | GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | @@ -382,9 +389,13 @@ nodes | GlobalDataFlow.cs:295:15:295:24 | access to parameter sinkParam9 | | GlobalDataFlow.cs:299:32:299:42 | sinkParam11 | | GlobalDataFlow.cs:301:15:301:25 | access to parameter sinkParam11 | +| GlobalDataFlow.cs:311:12:311:14 | return | | GlobalDataFlow.cs:313:16:313:29 | "taint source" | +| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | | GlobalDataFlow.cs:318:13:318:26 | "taint source" | +| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | | GlobalDataFlow.cs:323:13:323:26 | "taint source" | +| GlobalDataFlow.cs:326:25:326:32 | yield return | | GlobalDataFlow.cs:329:22:329:35 | "taint source" | | GlobalDataFlow.cs:354:41:354:41 | x | | GlobalDataFlow.cs:354:41:354:41 | x | @@ -396,11 +407,12 @@ nodes | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | +| GlobalDataFlow.cs:373:19:373:30 | return | | GlobalDataFlow.cs:373:39:373:45 | tainted | | GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | -| GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | | GlobalDataFlow.cs:399:9:399:11 | value | | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | +| GlobalDataFlow.cs:410:9:410:11 | return | | GlobalDataFlow.cs:410:22:410:35 | "taint source" | | Splitting.cs:3:28:3:34 | tainted | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | diff --git a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 1abc65684c6d..922a99229c08 100644 --- a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -14,6 +14,11 @@ | Capture.cs:58:21:58:21 | 1 | Capture.cs:58:17:58:21 | SSA def(i) | | Capture.cs:61:17:61:17 | 1 | Capture.cs:61:13:61:17 | SSA def(i) | | Capture.cs:63:9:63:17 | SSA call def(i) | Capture.cs:64:13:64:13 | access to local variable i | +| LocalDataFlow.cs:16:55:16:58 | null | LocalDataFlow.cs:16:42:16:44 | return | +| LocalDataFlow.cs:18:63:18:66 | null | LocalDataFlow.cs:18:50:18:52 | return | +| LocalDataFlow.cs:20:59:20:62 | null | LocalDataFlow.cs:20:46:20:48 | return | +| LocalDataFlow.cs:22:45:22:48 | null | LocalDataFlow.cs:22:32:22:34 | return | +| LocalDataFlow.cs:24:39:24:42 | null | LocalDataFlow.cs:24:26:24:28 | return | | LocalDataFlow.cs:49:30:49:30 | b | LocalDataFlow.cs:96:21:96:21 | access to parameter b | | LocalDataFlow.cs:52:13:52:34 | SSA def(sink0) | LocalDataFlow.cs:53:15:53:19 | access to local variable sink0 | | LocalDataFlow.cs:52:21:52:34 | "taint source" | LocalDataFlow.cs:52:13:52:34 | SSA def(sink0) | @@ -107,12 +112,14 @@ | LocalDataFlow.cs:136:22:136:55 | call to method First | LocalDataFlow.cs:136:13:136:55 | SSA def(sink14) | | LocalDataFlow.cs:136:35:136:35 | x | LocalDataFlow.cs:136:40:136:40 | access to parameter x | | LocalDataFlow.cs:136:40:136:40 | access to parameter x | LocalDataFlow.cs:136:40:136:46 | access to property Value | +| LocalDataFlow.cs:136:40:136:54 | ... != ... | LocalDataFlow.cs:136:35:136:54 | return | | LocalDataFlow.cs:140:9:140:55 | SSA def(nonSink3) | LocalDataFlow.cs:206:33:206:40 | access to local variable nonSink3 | | LocalDataFlow.cs:140:20:140:27 | access to local variable nonSink1 | LocalDataFlow.cs:141:15:141:22 | access to local variable nonSink1 | | LocalDataFlow.cs:140:20:140:55 | (...) ... | LocalDataFlow.cs:140:9:140:55 | SSA def(nonSink3) | | LocalDataFlow.cs:140:20:140:55 | call to method First | LocalDataFlow.cs:140:20:140:55 | (...) ... | | LocalDataFlow.cs:140:35:140:35 | x | LocalDataFlow.cs:140:40:140:40 | access to parameter x | | LocalDataFlow.cs:140:40:140:40 | access to parameter x | LocalDataFlow.cs:140:40:140:46 | access to property Value | +| LocalDataFlow.cs:140:40:140:54 | ... != ... | LocalDataFlow.cs:140:35:140:54 | return | | LocalDataFlow.cs:141:15:141:22 | access to local variable nonSink1 | LocalDataFlow.cs:214:20:214:27 | access to local variable nonSink1 | | LocalDataFlow.cs:144:13:144:39 | SSA def(sink15) | LocalDataFlow.cs:145:15:145:20 | access to local variable sink15 | | LocalDataFlow.cs:144:22:144:39 | call to method Parse | LocalDataFlow.cs:144:13:144:39 | SSA def(sink15) | @@ -310,6 +317,7 @@ | LocalDataFlow.cs:303:13:303:59 | SSA def(sink42) | LocalDataFlow.cs:304:15:304:20 | access to local variable sink42 | | LocalDataFlow.cs:303:22:303:59 | object creation of type Lazy | LocalDataFlow.cs:303:13:303:59 | SSA def(sink42) | | LocalDataFlow.cs:303:39:303:58 | [implicit call] (...) => ... | LocalDataFlow.cs:303:22:303:59 | object creation of type Lazy | +| LocalDataFlow.cs:303:45:303:58 | "taint source" | LocalDataFlow.cs:303:39:303:58 | return | | LocalDataFlow.cs:304:15:304:20 | access to local variable sink42 | LocalDataFlow.cs:305:22:305:27 | access to local variable sink42 | | LocalDataFlow.cs:305:13:305:33 | SSA def(sink43) | LocalDataFlow.cs:306:15:306:20 | access to local variable sink43 | | LocalDataFlow.cs:305:22:305:27 | access to local variable sink42 | LocalDataFlow.cs:305:22:305:33 | access to property Value | @@ -324,6 +332,7 @@ | LocalDataFlow.cs:313:9:313:46 | SSA def(nonSink12) | LocalDataFlow.cs:314:15:314:23 | access to local variable nonSink12 | | LocalDataFlow.cs:313:21:313:46 | object creation of type Lazy | LocalDataFlow.cs:313:9:313:46 | SSA def(nonSink12) | | LocalDataFlow.cs:313:38:313:45 | [implicit call] (...) => ... | LocalDataFlow.cs:313:21:313:46 | object creation of type Lazy | +| LocalDataFlow.cs:313:44:313:45 | "" | LocalDataFlow.cs:313:38:313:45 | return | | LocalDataFlow.cs:314:15:314:23 | access to local variable nonSink12 | LocalDataFlow.cs:315:20:315:28 | access to local variable nonSink12 | | LocalDataFlow.cs:315:9:315:34 | SSA def(nonSink0) | LocalDataFlow.cs:316:15:316:22 | access to local variable nonSink0 | | LocalDataFlow.cs:315:20:315:28 | access to local variable nonSink12 | LocalDataFlow.cs:315:20:315:34 | access to property Value | @@ -418,6 +427,7 @@ | LocalDataFlow.cs:391:13:391:51 | SSA def(sink67) | LocalDataFlow.cs:392:15:392:20 | access to local variable sink67 | | LocalDataFlow.cs:391:22:391:51 | call to method Run | LocalDataFlow.cs:391:13:391:51 | SSA def(sink67) | | LocalDataFlow.cs:391:31:391:50 | [implicit call] (...) => ... | LocalDataFlow.cs:391:22:391:51 | call to method Run | +| LocalDataFlow.cs:391:37:391:50 | "taint source" | LocalDataFlow.cs:391:31:391:50 | return | | LocalDataFlow.cs:392:15:392:20 | access to local variable sink67 | LocalDataFlow.cs:393:28:393:33 | access to local variable sink67 | | LocalDataFlow.cs:393:13:393:33 | SSA def(sink68) | LocalDataFlow.cs:394:15:394:20 | access to local variable sink68 | | LocalDataFlow.cs:393:22:393:33 | await ... | LocalDataFlow.cs:393:13:393:33 | SSA def(sink68) | @@ -425,6 +435,7 @@ | LocalDataFlow.cs:397:13:397:42 | SSA def(nonSink21) | LocalDataFlow.cs:398:15:398:23 | access to local variable nonSink21 | | LocalDataFlow.cs:397:25:397:42 | call to method Run | LocalDataFlow.cs:397:13:397:42 | SSA def(nonSink21) | | LocalDataFlow.cs:397:34:397:41 | [implicit call] (...) => ... | LocalDataFlow.cs:397:25:397:42 | call to method Run | +| LocalDataFlow.cs:397:40:397:41 | "" | LocalDataFlow.cs:397:34:397:41 | return | | LocalDataFlow.cs:398:15:398:23 | access to local variable nonSink21 | LocalDataFlow.cs:399:26:399:34 | access to local variable nonSink21 | | LocalDataFlow.cs:399:9:399:34 | SSA def(nonSink0) | LocalDataFlow.cs:400:15:400:22 | access to local variable nonSink0 | | LocalDataFlow.cs:399:20:399:34 | await ... | LocalDataFlow.cs:399:9:399:34 | SSA def(nonSink0) | @@ -453,6 +464,9 @@ | LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) | LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 | | LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | LocalDataFlow.cs:438:23:438:31 | access to local variable nonSink17 | +| LocalDataFlow.cs:447:37:447:38 | "" | LocalDataFlow.cs:447:12:447:24 | return | +| LocalDataFlow.cs:449:40:449:41 | "" | LocalDataFlow.cs:449:12:449:27 | return | +| LocalDataFlow.cs:458:41:458:45 | access to field anInt | LocalDataFlow.cs:458:28:458:30 | return | | LocalDataFlow.cs:458:50:458:52 | value | LocalDataFlow.cs:458:64:458:68 | access to parameter value | | LocalDataFlow.cs:464:41:464:47 | tainted | LocalDataFlow.cs:466:15:466:21 | access to parameter tainted | | LocalDataFlow.cs:469:44:469:53 | nonTainted | LocalDataFlow.cs:471:15:471:24 | access to parameter nonTainted | @@ -624,8 +638,10 @@ | SSA.cs:146:13:146:13 | access to parameter t | SSA.cs:146:13:146:13 | (...) ... | | SSA.cs:146:13:146:13 | access to parameter t | SSA.cs:149:17:149:17 | access to parameter t | | SSA.cs:147:13:147:26 | SSA def(t) | SSA.cs:144:17:144:26 | SSA phi(t) | +| SSA.cs:147:17:147:26 | default(...) | SSA.cs:144:34:144:34 | return (out/ref) | | SSA.cs:147:17:147:26 | default(...) | SSA.cs:147:13:147:26 | SSA def(t) | | SSA.cs:149:13:149:17 | SSA def(t) | SSA.cs:144:17:144:26 | SSA phi(t) | +| SSA.cs:149:17:149:17 | access to parameter t | SSA.cs:144:34:144:34 | return (out/ref) | | SSA.cs:149:17:149:17 | access to parameter t | SSA.cs:149:13:149:17 | SSA def(t) | | SSA.cs:152:36:152:36 | t | SSA.cs:154:13:154:13 | access to parameter t | | SSA.cs:154:13:154:13 | access to parameter t | SSA.cs:152:17:152:28 | SSA phi(t) | diff --git a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected index b68b6ffbfd61..6ad6a3ba0baf 100644 --- a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected @@ -14,6 +14,11 @@ | Capture.cs:58:21:58:21 | 1 | Capture.cs:58:17:58:21 | SSA def(i) | | Capture.cs:61:17:61:17 | 1 | Capture.cs:61:13:61:17 | SSA def(i) | | Capture.cs:63:9:63:17 | SSA call def(i) | Capture.cs:64:13:64:13 | access to local variable i | +| LocalDataFlow.cs:16:55:16:58 | null | LocalDataFlow.cs:16:42:16:44 | return | +| LocalDataFlow.cs:18:63:18:66 | null | LocalDataFlow.cs:18:50:18:52 | return | +| LocalDataFlow.cs:20:59:20:62 | null | LocalDataFlow.cs:20:46:20:48 | return | +| LocalDataFlow.cs:22:45:22:48 | null | LocalDataFlow.cs:22:32:22:34 | return | +| LocalDataFlow.cs:24:39:24:42 | null | LocalDataFlow.cs:24:26:24:28 | return | | LocalDataFlow.cs:49:30:49:30 | b | LocalDataFlow.cs:96:21:96:21 | access to parameter b | | LocalDataFlow.cs:52:13:52:34 | SSA def(sink0) | LocalDataFlow.cs:53:15:53:19 | access to local variable sink0 | | LocalDataFlow.cs:52:21:52:34 | "taint source" | LocalDataFlow.cs:52:13:52:34 | SSA def(sink0) | @@ -131,6 +136,7 @@ | LocalDataFlow.cs:136:35:136:35 | x | LocalDataFlow.cs:136:40:136:40 | access to parameter x | | LocalDataFlow.cs:136:40:136:40 | access to parameter x | LocalDataFlow.cs:136:40:136:46 | access to property Value | | LocalDataFlow.cs:136:40:136:46 | access to property Value | LocalDataFlow.cs:136:40:136:54 | ... != ... | +| LocalDataFlow.cs:136:40:136:54 | ... != ... | LocalDataFlow.cs:136:35:136:54 | return | | LocalDataFlow.cs:140:9:140:55 | SSA def(nonSink3) | LocalDataFlow.cs:206:33:206:40 | access to local variable nonSink3 | | LocalDataFlow.cs:140:20:140:27 | access to local variable nonSink1 | LocalDataFlow.cs:140:20:140:55 | call to method First | | LocalDataFlow.cs:140:20:140:27 | access to local variable nonSink1 | LocalDataFlow.cs:141:15:141:22 | access to local variable nonSink1 | @@ -139,6 +145,7 @@ | LocalDataFlow.cs:140:35:140:35 | x | LocalDataFlow.cs:140:40:140:40 | access to parameter x | | LocalDataFlow.cs:140:40:140:40 | access to parameter x | LocalDataFlow.cs:140:40:140:46 | access to property Value | | LocalDataFlow.cs:140:40:140:46 | access to property Value | LocalDataFlow.cs:140:40:140:54 | ... != ... | +| LocalDataFlow.cs:140:40:140:54 | ... != ... | LocalDataFlow.cs:140:35:140:54 | return | | LocalDataFlow.cs:141:15:141:22 | access to local variable nonSink1 | LocalDataFlow.cs:214:20:214:27 | access to local variable nonSink1 | | LocalDataFlow.cs:144:13:144:39 | SSA def(sink15) | LocalDataFlow.cs:145:15:145:20 | access to local variable sink15 | | LocalDataFlow.cs:144:22:144:39 | call to method Parse | LocalDataFlow.cs:144:13:144:39 | SSA def(sink15) | @@ -426,6 +433,7 @@ | LocalDataFlow.cs:303:13:303:59 | SSA def(sink42) | LocalDataFlow.cs:304:15:304:20 | access to local variable sink42 | | LocalDataFlow.cs:303:22:303:59 | object creation of type Lazy | LocalDataFlow.cs:303:13:303:59 | SSA def(sink42) | | LocalDataFlow.cs:303:39:303:58 | [implicit call] (...) => ... | LocalDataFlow.cs:303:22:303:59 | object creation of type Lazy | +| LocalDataFlow.cs:303:45:303:58 | "taint source" | LocalDataFlow.cs:303:39:303:58 | return | | LocalDataFlow.cs:304:15:304:20 | access to local variable sink42 | LocalDataFlow.cs:305:22:305:27 | access to local variable sink42 | | LocalDataFlow.cs:305:13:305:33 | SSA def(sink43) | LocalDataFlow.cs:306:15:306:20 | access to local variable sink43 | | LocalDataFlow.cs:305:22:305:27 | access to local variable sink42 | LocalDataFlow.cs:305:22:305:33 | access to property Value | @@ -440,6 +448,7 @@ | LocalDataFlow.cs:313:9:313:46 | SSA def(nonSink12) | LocalDataFlow.cs:314:15:314:23 | access to local variable nonSink12 | | LocalDataFlow.cs:313:21:313:46 | object creation of type Lazy | LocalDataFlow.cs:313:9:313:46 | SSA def(nonSink12) | | LocalDataFlow.cs:313:38:313:45 | [implicit call] (...) => ... | LocalDataFlow.cs:313:21:313:46 | object creation of type Lazy | +| LocalDataFlow.cs:313:44:313:45 | "" | LocalDataFlow.cs:313:38:313:45 | return | | LocalDataFlow.cs:314:15:314:23 | access to local variable nonSink12 | LocalDataFlow.cs:315:20:315:28 | access to local variable nonSink12 | | LocalDataFlow.cs:315:9:315:34 | SSA def(nonSink0) | LocalDataFlow.cs:316:15:316:22 | access to local variable nonSink0 | | LocalDataFlow.cs:315:20:315:28 | access to local variable nonSink12 | LocalDataFlow.cs:315:20:315:34 | access to property Value | @@ -556,6 +565,7 @@ | LocalDataFlow.cs:391:13:391:51 | SSA def(sink67) | LocalDataFlow.cs:392:15:392:20 | access to local variable sink67 | | LocalDataFlow.cs:391:22:391:51 | call to method Run | LocalDataFlow.cs:391:13:391:51 | SSA def(sink67) | | LocalDataFlow.cs:391:31:391:50 | [implicit call] (...) => ... | LocalDataFlow.cs:391:22:391:51 | call to method Run | +| LocalDataFlow.cs:391:37:391:50 | "taint source" | LocalDataFlow.cs:391:31:391:50 | return | | LocalDataFlow.cs:392:15:392:20 | access to local variable sink67 | LocalDataFlow.cs:393:28:393:33 | access to local variable sink67 | | LocalDataFlow.cs:393:13:393:33 | SSA def(sink68) | LocalDataFlow.cs:394:15:394:20 | access to local variable sink68 | | LocalDataFlow.cs:393:22:393:33 | await ... | LocalDataFlow.cs:393:13:393:33 | SSA def(sink68) | @@ -563,6 +573,7 @@ | LocalDataFlow.cs:397:13:397:42 | SSA def(nonSink21) | LocalDataFlow.cs:398:15:398:23 | access to local variable nonSink21 | | LocalDataFlow.cs:397:25:397:42 | call to method Run | LocalDataFlow.cs:397:13:397:42 | SSA def(nonSink21) | | LocalDataFlow.cs:397:34:397:41 | [implicit call] (...) => ... | LocalDataFlow.cs:397:25:397:42 | call to method Run | +| LocalDataFlow.cs:397:40:397:41 | "" | LocalDataFlow.cs:397:34:397:41 | return | | LocalDataFlow.cs:398:15:398:23 | access to local variable nonSink21 | LocalDataFlow.cs:399:26:399:34 | access to local variable nonSink21 | | LocalDataFlow.cs:399:9:399:34 | SSA def(nonSink0) | LocalDataFlow.cs:400:15:400:22 | access to local variable nonSink0 | | LocalDataFlow.cs:399:20:399:34 | await ... | LocalDataFlow.cs:399:9:399:34 | SSA def(nonSink0) | @@ -595,6 +606,9 @@ | LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) | LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 | | LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | LocalDataFlow.cs:438:23:438:31 | access to local variable nonSink17 | +| LocalDataFlow.cs:447:37:447:38 | "" | LocalDataFlow.cs:447:12:447:24 | return | +| LocalDataFlow.cs:449:40:449:41 | "" | LocalDataFlow.cs:449:12:449:27 | return | +| LocalDataFlow.cs:458:41:458:45 | access to field anInt | LocalDataFlow.cs:458:28:458:30 | return | | LocalDataFlow.cs:458:50:458:52 | value | LocalDataFlow.cs:458:64:458:68 | access to parameter value | | LocalDataFlow.cs:464:41:464:47 | tainted | LocalDataFlow.cs:466:15:466:21 | access to parameter tainted | | LocalDataFlow.cs:469:44:469:53 | nonTainted | LocalDataFlow.cs:471:15:471:24 | access to parameter nonTainted | @@ -781,8 +795,10 @@ | SSA.cs:146:13:146:13 | access to parameter t | SSA.cs:146:13:146:13 | (...) ... | | SSA.cs:146:13:146:13 | access to parameter t | SSA.cs:149:17:149:17 | access to parameter t | | SSA.cs:147:13:147:26 | SSA def(t) | SSA.cs:144:17:144:26 | SSA phi(t) | +| SSA.cs:147:17:147:26 | default(...) | SSA.cs:144:34:144:34 | return (out/ref) | | SSA.cs:147:17:147:26 | default(...) | SSA.cs:147:13:147:26 | SSA def(t) | | SSA.cs:149:13:149:17 | SSA def(t) | SSA.cs:144:17:144:26 | SSA phi(t) | +| SSA.cs:149:17:149:17 | access to parameter t | SSA.cs:144:34:144:34 | return (out/ref) | | SSA.cs:149:17:149:17 | access to parameter t | SSA.cs:149:13:149:17 | SSA def(t) | | SSA.cs:152:36:152:36 | t | SSA.cs:154:13:154:13 | access to parameter t | | SSA.cs:154:13:154:13 | (...) ... | SSA.cs:154:13:154:21 | ... == ... | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected index a5fb3480409d..9cd83abf87ca 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected @@ -1,23 +1,30 @@ edges +| InsecureRandomness.cs:21:26:21:45 | return | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | +| InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:21:26:21:45 | return | | InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:29:27:29:61 | call to method GetString | | InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:31:16:31:32 | call to method ToString | +| InsecureRandomness.cs:29:27:29:61 | call to method GetString | InsecureRandomness.cs:21:26:21:45 | return | | InsecureRandomness.cs:29:27:29:61 | call to method GetString | InsecureRandomness.cs:31:16:31:32 | call to method ToString | -| InsecureRandomness.cs:31:16:31:32 | call to method ToString | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | +| InsecureRandomness.cs:31:16:31:32 | call to method ToString | InsecureRandomness.cs:21:26:21:45 | return | +| InsecureRandomness.cs:53:26:53:58 | return | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | +| InsecureRandomness.cs:60:31:60:39 | call to method Next | InsecureRandomness.cs:53:26:53:58 | return | | InsecureRandomness.cs:60:31:60:39 | call to method Next | InsecureRandomness.cs:62:16:62:32 | call to method ToString | -| InsecureRandomness.cs:62:16:62:32 | call to method ToString | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | -| InsecureRandomness.cs:72:31:72:39 | call to method Next | InsecureRandomness.cs:74:16:74:21 | access to local variable result | -| InsecureRandomness.cs:74:16:74:21 | access to local variable result | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | +| InsecureRandomness.cs:62:16:62:32 | call to method ToString | InsecureRandomness.cs:53:26:53:58 | return | +| InsecureRandomness.cs:65:26:65:56 | return | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | +| InsecureRandomness.cs:72:31:72:39 | call to method Next | InsecureRandomness.cs:65:26:65:56 | return | nodes | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | +| InsecureRandomness.cs:21:26:21:45 | return | | InsecureRandomness.cs:28:29:28:43 | call to method Next | | InsecureRandomness.cs:29:27:29:61 | call to method GetString | | InsecureRandomness.cs:31:16:31:32 | call to method ToString | +| InsecureRandomness.cs:53:26:53:58 | return | | InsecureRandomness.cs:60:31:60:39 | call to method Next | | InsecureRandomness.cs:62:16:62:32 | call to method ToString | +| InsecureRandomness.cs:65:26:65:56 | return | | InsecureRandomness.cs:72:31:72:39 | call to method Next | -| InsecureRandomness.cs:74:16:74:21 | access to local variable result | #select | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | Cryptographically insecure random number is generated at $@ and used here in a security context. | InsecureRandomness.cs:28:29:28:43 | call to method Next | call to method Next | | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | InsecureRandomness.cs:60:31:60:39 | call to method Next | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | Cryptographically insecure random number is generated at $@ and used here in a security context. | InsecureRandomness.cs:60:31:60:39 | call to method Next | call to method Next | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected b/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected index 5f031e3db297..3355a8a45909 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected @@ -6,7 +6,8 @@ edges | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | InappropriateEncoding.cs:38:22:38:59 | ... + ... | | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | InappropriateEncoding.cs:39:22:39:71 | call to method Format | | InappropriateEncoding.cs:57:28:57:56 | call to method HtmlEncode | InappropriateEncoding.cs:58:31:58:42 | access to local variable encodedValue | -| InappropriateEncoding.cs:68:16:68:42 | call to method Replace | InappropriateEncoding.cs:15:28:15:40 | call to method Encode | +| InappropriateEncoding.cs:66:19:66:24 | return | InappropriateEncoding.cs:15:28:15:40 | call to method Encode | +| InappropriateEncoding.cs:68:16:68:42 | call to method Replace | InappropriateEncoding.cs:66:19:66:24 | return | | SqlEncode.cs:16:62:16:87 | call to method Replace | SqlEncode.cs:17:46:17:50 | access to local variable query | | UrlEncode.cs:12:43:12:69 | call to method HtmlEncode | UrlEncode.cs:12:31:12:69 | ... + ... | nodes @@ -25,6 +26,7 @@ nodes | InappropriateEncoding.cs:39:22:39:71 | call to method Format | | InappropriateEncoding.cs:57:28:57:56 | call to method HtmlEncode | | InappropriateEncoding.cs:58:31:58:42 | access to local variable encodedValue | +| InappropriateEncoding.cs:66:19:66:24 | return | | InappropriateEncoding.cs:68:16:68:42 | call to method Replace | | SqlEncode.cs:16:62:16:87 | call to method Replace | | SqlEncode.cs:17:46:17:50 | access to local variable query | From 397cc56a6fec10c7dbab260e9e0b1855f3c6ff81 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 5 Mar 2019 20:50:22 +0100 Subject: [PATCH 5/7] C#: Cache `DataFlow::Node::getLocation()` --- .../semmle/code/csharp/controlflow/Guards.qll | 2 +- .../semmle/code/csharp/dataflow/DataFlow.qll | 91 +++++++++---------- 2 files changed, 46 insertions(+), 47 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll b/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll index 276791be5ccd..0dffebb4a66e 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll @@ -1221,7 +1221,7 @@ module Internal { exists(Guard g | e = g.getAChildExpr*() | g.controls(bb, _) or - g.assertionControlsElement(bb.getANode().getElement(), _) + g.assertionControlsNode(bb.getANode(), _) ) } } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index 70fcfb2af1ee..f866c784e2b1 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -34,14 +34,13 @@ module DataFlow { DotNet::Type getType() { none() } /** Gets the enclosing callable of this node. */ - cached - DotNet::Callable getEnclosingCallable() { none() } + final DotNet::Callable getEnclosingCallable() { result = getEnclosingCallable(this) } /** Gets a textual representation of this node. */ string toString() { none() } /** Gets the location of this node. */ - Location getLocation() { none() } + final Location getLocation() { result = getLocation(this) } } /** @@ -65,25 +64,12 @@ module DataFlow { override DotNet::Type getType() { result = this.getExpr().getType() } - override DotNet::Callable getEnclosingCallable() { - result = this.getExpr().getEnclosingCallable() - } - override string toString() { exists(ControlFlow::Nodes::ElementNode cfn | this = TExprNode(cfn) | result = cfn.toString()) or this = TCilExprNode(_) and result = "CIL expression" } - - override Location getLocation() { - exists(ControlFlow::Nodes::ElementNode cfn | this = TExprNode(cfn) | - result = cfn.getLocation() - ) - or - result.getFile().isPdbSourceFile() and - exists(CIL::Expr e | this = TCilExprNode(e) | result = e.getALocation()) - } } /** @@ -278,16 +264,10 @@ module DataFlow { override Type getType() { result = def.getSourceVariable().getType() } - override Callable getEnclosingCallable() { - result = def.getSourceVariable().getEnclosingCallable() - } - override string toString() { result = def.toString() and not this instanceof ExplicitParameterNode } - - override Location getLocation() { result = def.getLocation() } } /** @@ -318,11 +298,7 @@ module DataFlow { override DotNet::Type getType() { result = parameter.getType() } - override DotNet::Callable getEnclosingCallable() { result = parameter.getCallable() } - override string toString() { result = parameter.toString() } - - override Location getLocation() { result = parameter.getLocation() } } /** @@ -409,11 +385,7 @@ module DataFlow { override Type getType() { result = arg.getType() } - override Callable getEnclosingCallable() { result = arg.getEnclosingCallable() } - override string toString() { result = "[implicit call] " + arg.toString() } - - override Location getLocation() { result = arg.getLocation() } } /** A data flow node that represents the output of a call. */ @@ -568,11 +540,7 @@ module DataFlow { override Type getType() { result = v.getType() } - override Callable getEnclosingCallable() { result = c.getEnclosingCallable() } - override string toString() { result = v + " [implicit argument]" } - - override Location getLocation() { result = c.getLocation() } } /** @@ -587,11 +555,7 @@ module DataFlow { class NormalReturnNode extends ReturnNode, TNormalReturnNode { override Type getType() { result = this.getEnclosingCallable().getReturnType() } - override DotNet::Callable getEnclosingCallable() { this = TNormalReturnNode(result) } - override string toString() { result = "return" } - - override Location getLocation() { result = this.getEnclosingCallable().getLocation() } } /** @@ -601,11 +565,7 @@ module DataFlow { class YieldReturnNode extends ReturnNode, TYieldReturnNode { override Type getType() { result = this.getEnclosingCallable().getReturnType() } - override Callable getEnclosingCallable() { this = TYieldReturnNode(result) } - override string toString() { result = "yield return" } - - override Location getLocation() { result = this.getEnclosingCallable().getLocation() } } /** @@ -617,11 +577,7 @@ module DataFlow { override Type getType() { result = this.getParameter().getType() } - override Callable getEnclosingCallable() { result = this.getParameter().getCallable() } - override string toString() { result = "return (out/ref)" } - - override Location getLocation() { result = this.getParameter().getLocation() } } /** @@ -1453,6 +1409,49 @@ module DataFlow { TYieldReturnNode(Callable c) { c.canYieldReturn(_) } or TOutRefReturnNode(Parameter p) { callableReturnsOutOrRef(_, p, _) } + cached + DotNet::Callable getEnclosingCallable(Node node) { + result = node.(ExprNode).getExpr().getEnclosingCallable() + or + result = node.(SsaDefinitionNode).getDefinition().getSourceVariable().getEnclosingCallable() + or + result = node.(ExplicitParameterNode).getParameter().getCallable() + or + result = node.(ImplicitDelegateCallNode).getArgument().getEnclosingCallable() + or + result = node.(ImplicitCapturedArgumentNode).getCall().getEnclosingCallable() + or + node = TNormalReturnNode(result) + or + node = TYieldReturnNode(result) + or + result = node.(OutRefReturnNode).getParameter().getCallable() + } + + cached + Location getLocation(Node node) { + exists(ControlFlow::Nodes::ElementNode cfn | node = TExprNode(cfn) | + result = cfn.getLocation() + ) + or + result.getFile().isPdbSourceFile() and + exists(CIL::Expr e | node = TCilExprNode(e) | result = e.getALocation()) + or + result = node.(SsaDefinitionNode).getDefinition().getLocation() + or + result = node.(ExplicitParameterNode).getParameter().getLocation() + or + result = node.(ImplicitDelegateCallNode).getArgument().getLocation() + or + result = node.(ImplicitCapturedArgumentNode).getCall().getLocation() + or + result = node.(NormalReturnNode).getEnclosingCallable().getLocation() + or + result = node.(YieldReturnNode).getEnclosingCallable().getLocation() + or + result = node.(OutRefReturnNode).getParameter().getLocation() + } + /** * Holds if `pred` can flow to `succ`, by jumping from one callable to * another. From b48576d7b906f04364847d458cfb9a286e216413 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 10 Mar 2019 15:45:31 +0100 Subject: [PATCH 6/7] C#: Address review comments --- .../semmle/code/csharp/dataflow/DataFlow.qll | 30 ++++----- .../csharp7/LocalTaintFlow.expected | 66 +++++++++---------- .../csharp7/TaintReaches.expected | 4 +- .../dataflow/global/DataFlowPath.expected | 38 +++++------ .../global/TaintTrackingPath.expected | 44 ++++++------- .../dataflow/local/DataFlowStep.expected | 32 ++++----- .../dataflow/local/TaintTrackingStep.expected | 32 ++++----- .../CWE-338/InsecureRandomness.expected | 24 +++---- .../CWE-838/InappropriateEncoding.expected | 6 +- 9 files changed, 137 insertions(+), 139 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index 306b5f020109..e6a873a16cc4 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -565,7 +565,7 @@ module DataFlow { class NormalReturnNode extends ReturnNode, TNormalReturnNode { override Type getType() { result = this.getEnclosingCallable().getReturnType() } - override string toString() { result = "return" } + override string toString() { result = "return " + this.getEnclosingCallable() } } /** @@ -575,7 +575,7 @@ module DataFlow { class YieldReturnNode extends ReturnNode, TYieldReturnNode { override Type getType() { result = this.getEnclosingCallable().getReturnType() } - override string toString() { result = "yield return" } + override string toString() { result = "yield return " + this.getEnclosingCallable() } } /** @@ -587,7 +587,7 @@ module DataFlow { override Type getType() { result = this.getParameter().getType() } - override string toString() { result = "return (out/ref)" } + override string toString() { result = "return (out/ref) " + this.getEnclosingCallable() } } /** @@ -1073,7 +1073,9 @@ module DataFlow { } pragma[noinline] - private predicate localFlowStep0(Node pred, Node succ, Configuration config, DotNet::Callable c) { + private predicate localFlowStep0( + Node pred, Node succ, Configuration config, DotNet::Callable c + ) { config.isAdditionalFlowStep(pred, succ) and pred.getEnclosingCallable() = c } @@ -1099,9 +1101,7 @@ module DataFlow { jumpStep(_, node, config) or node instanceof ParameterNode or node instanceof OutNode or - node instanceof NormalReturnNode or - node instanceof YieldReturnNode or - node instanceof OutRefReturnNode + node instanceof ReturnNode ) } @@ -1118,11 +1118,7 @@ module DataFlow { or node instanceof ReturnNode or - exists(ReturnNode rn | localFlowStep(node, rn, config) | - rn instanceof NormalReturnNode or - rn instanceof YieldReturnNode or - rn instanceof OutRefReturnNode - ) + localFlowStep(node, any(ReturnNode rn), config) or config.isSink(node) ) @@ -1286,7 +1282,7 @@ module DataFlow { flowIntoCallableStep(call, arg, p, _, config) } - // noopt is need to force scan of `nodeCand1()` followed by join on + // noopt is needed to force scan of `nodeCand1()` followed by join on // `flowOutOfCallableStep()`, instead of the other way around pragma[noopt] private predicate flowOutOfCallableStepCand1( @@ -1344,7 +1340,7 @@ module DataFlow { flowIntoCallableStep(_, arg, p, _, config) } - // noopt is need to force scan of `nodeCandFwd2()` followed by join on + // noopt is needed to force scan of `nodeCandFwd2()` followed by join on // `flowOutOfCallableStep()`, instead of the other way around pragma[noopt] private predicate flowOutOfCallableStepCandFwd2( @@ -1405,7 +1401,7 @@ module DataFlow { flowIntoCallableStep(call, arg, p, cc, config) } - // noopt is need to force scan of `nodeCand()` followed by join on + // noopt is needed to force scan of `nodeCand()` followed by join on // `flowOutOfCallableStep()`, instead of the other way around pragma[noopt] predicate flowOutOfCallableStepCand( @@ -1658,7 +1654,9 @@ module DataFlow { /** * A data flow context describing flow into a callable via a call argument. */ - abstract private class ArgumentContext extends Context { abstract DotNet::Expr getCall(); } + abstract private class ArgumentContext extends Context { + abstract DotNet::Expr getCall(); + } /** * A data flow context describing flow into a callable via an explicit call argument. diff --git a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected index ff611fa08501..a3b3be6c7662 100644 --- a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected +++ b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected @@ -1,27 +1,27 @@ -| CSharp7.cs:17:18:17:22 | access to field field | CSharp7.cs:17:9:17:11 | return | -| CSharp7.cs:18:14:18:14 | 5 | CSharp7.cs:18:14:18:14 | return | -| CSharp7.cs:21:16:21:20 | call to method Foo | CSharp7.cs:21:9:21:11 | return | +| CSharp7.cs:17:18:17:22 | access to field field | CSharp7.cs:17:9:17:11 | return Foo | +| CSharp7.cs:18:14:18:14 | 5 | CSharp7.cs:18:14:18:14 | return get_P | +| CSharp7.cs:21:16:21:20 | call to method Foo | CSharp7.cs:21:9:21:11 | return get_Q | | CSharp7.cs:22:9:22:11 | value | CSharp7.cs:22:24:22:28 | access to parameter value | -| CSharp7.cs:22:16:22:28 | ... = ... | CSharp7.cs:22:9:22:11 | return | -| CSharp7.cs:25:39:25:43 | call to method Foo | CSharp7.cs:25:5:25:27 | return | -| CSharp7.cs:26:35:26:39 | call to method Foo | CSharp7.cs:26:6:26:28 | return | +| CSharp7.cs:22:16:22:28 | ... = ... | CSharp7.cs:22:9:22:11 | return set_Q | +| CSharp7.cs:25:39:25:43 | call to method Foo | CSharp7.cs:25:5:25:27 | return ExpressionBodiedMembers | +| CSharp7.cs:26:35:26:39 | call to method Foo | CSharp7.cs:26:6:26:28 | return ~ExpressionBodiedMembers | | CSharp7.cs:31:19:31:19 | i | CSharp7.cs:33:16:33:16 | access to parameter i | | CSharp7.cs:33:16:33:16 | access to parameter i | CSharp7.cs:33:16:33:20 | ... > ... | | CSharp7.cs:33:16:33:16 | access to parameter i | CSharp7.cs:33:24:33:24 | access to parameter i | | CSharp7.cs:33:16:33:20 | ... > ... | CSharp7.cs:33:16:33:59 | ... ? ... : ... | -| CSharp7.cs:33:16:33:59 | ... ? ... : ... | CSharp7.cs:31:9:31:13 | return | +| CSharp7.cs:33:16:33:59 | ... ? ... : ... | CSharp7.cs:31:9:31:13 | return Throw | | CSharp7.cs:33:24:33:24 | access to parameter i | CSharp7.cs:33:16:33:59 | ... ? ... : ... | | CSharp7.cs:33:28:33:59 | throw ... | CSharp7.cs:33:16:33:59 | ... ? ... : ... | -| CSharp7.cs:41:13:41:21 | "tainted" | CSharp7.cs:39:23:39:23 | return (out/ref) | +| CSharp7.cs:41:13:41:21 | "tainted" | CSharp7.cs:39:23:39:23 | return (out/ref) F | | CSharp7.cs:41:13:41:21 | "tainted" | CSharp7.cs:41:9:41:21 | SSA def(x) | | CSharp7.cs:44:19:44:19 | x | CSharp7.cs:46:13:46:13 | access to parameter x | -| CSharp7.cs:46:13:46:13 | access to parameter x | CSharp7.cs:44:33:44:33 | return (out/ref) | +| CSharp7.cs:46:13:46:13 | access to parameter x | CSharp7.cs:44:33:44:33 | return (out/ref) G | | CSharp7.cs:46:13:46:13 | access to parameter x | CSharp7.cs:46:9:46:13 | SSA def(y) | | CSharp7.cs:51:22:51:23 | SSA def(t1) | CSharp7.cs:53:18:53:19 | access to local variable t1 | | CSharp7.cs:52:19:52:20 | SSA def(t2) | CSharp7.cs:56:14:56:15 | access to local variable t2 | | CSharp7.cs:54:15:54:16 | SSA def(t1) | CSharp7.cs:55:14:55:15 | access to local variable t1 | | CSharp7.cs:57:30:57:31 | SSA def(t4) | CSharp7.cs:58:18:58:19 | access to local variable t4 | -| CSharp7.cs:66:16:66:21 | (..., ...) | CSharp7.cs:64:16:64:16 | return | +| CSharp7.cs:66:16:66:21 | (..., ...) | CSharp7.cs:64:16:64:16 | return F | | CSharp7.cs:66:17:66:17 | 1 | CSharp7.cs:66:16:66:21 | (..., ...) | | CSharp7.cs:66:20:66:20 | 2 | CSharp7.cs:66:16:66:21 | (..., ...) | | CSharp7.cs:72:13:72:19 | SSA def(z) | CSharp7.cs:75:16:75:16 | access to local variable z | @@ -49,7 +49,7 @@ | CSharp7.cs:79:27:79:27 | access to local variable x | CSharp7.cs:79:22:79:28 | (..., ...) | | CSharp7.cs:82:21:82:21 | x | CSharp7.cs:84:20:84:20 | access to parameter x | | CSharp7.cs:84:16:84:24 | (..., ...) | CSharp7.cs:84:16:84:26 | access to field a | -| CSharp7.cs:84:16:84:26 | access to field a | CSharp7.cs:82:12:82:12 | return | +| CSharp7.cs:84:16:84:26 | access to field a | CSharp7.cs:82:12:82:12 | return I | | CSharp7.cs:84:20:84:20 | access to parameter x | CSharp7.cs:84:16:84:24 | (..., ...) | | CSharp7.cs:84:23:84:23 | 2 | CSharp7.cs:84:16:84:24 | (..., ...) | | CSharp7.cs:89:13:89:34 | SSA def(t1) | CSharp7.cs:90:28:90:29 | access to local variable t1 | @@ -97,47 +97,47 @@ | CSharp7.cs:123:28:123:36 | "DefUse3" | CSharp7.cs:123:22:123:36 | ... = ... | | CSharp7.cs:131:20:131:20 | x | CSharp7.cs:131:32:131:32 | access to parameter x | | CSharp7.cs:131:32:131:32 | access to parameter x | CSharp7.cs:131:32:131:36 | ... + ... | -| CSharp7.cs:131:32:131:36 | ... + ... | CSharp7.cs:131:9:131:39 | return | +| CSharp7.cs:131:32:131:36 | ... + ... | CSharp7.cs:131:9:131:39 | return f1 | | CSharp7.cs:131:36:131:36 | 1 | CSharp7.cs:131:32:131:36 | ... + ... | | CSharp7.cs:133:22:133:22 | t | CSharp7.cs:133:39:133:39 | access to parameter t | -| CSharp7.cs:133:39:133:39 | access to parameter t | CSharp7.cs:133:9:133:42 | return | -| CSharp7.cs:137:21:137:21 | 2 | CSharp7.cs:137:9:137:22 | return | +| CSharp7.cs:133:39:133:39 | access to parameter t | CSharp7.cs:133:9:133:42 | return f2 | +| CSharp7.cs:137:21:137:21 | 2 | CSharp7.cs:137:9:137:22 | return f3 | | CSharp7.cs:139:29:139:29 | x | CSharp7.cs:139:34:139:34 | access to parameter x | | CSharp7.cs:139:34:139:34 | access to parameter x | CSharp7.cs:139:34:139:38 | ... + ... | -| CSharp7.cs:139:34:139:38 | ... + ... | CSharp7.cs:139:29:139:38 | return | +| CSharp7.cs:139:34:139:38 | ... + ... | CSharp7.cs:139:29:139:38 | return (...) => ... | | CSharp7.cs:139:38:139:38 | 1 | CSharp7.cs:139:34:139:38 | ... + ... | | CSharp7.cs:141:20:141:20 | x | CSharp7.cs:141:26:141:26 | access to parameter x | | CSharp7.cs:141:26:141:26 | access to parameter x | CSharp7.cs:141:26:141:30 | ... > ... | | CSharp7.cs:141:26:141:26 | access to parameter x | CSharp7.cs:141:41:141:41 | access to parameter x | | CSharp7.cs:141:26:141:30 | ... > ... | CSharp7.cs:141:26:141:50 | ... ? ... : ... | -| CSharp7.cs:141:26:141:50 | ... ? ... : ... | CSharp7.cs:141:9:141:51 | return | +| CSharp7.cs:141:26:141:50 | ... ? ... : ... | CSharp7.cs:141:9:141:51 | return f6 | | CSharp7.cs:141:34:141:34 | 1 | CSharp7.cs:141:34:141:46 | ... + ... | | CSharp7.cs:141:34:141:46 | ... + ... | CSharp7.cs:141:26:141:50 | ... ? ... : ... | | CSharp7.cs:141:38:141:46 | call to local function f7 | CSharp7.cs:141:34:141:46 | ... + ... | | CSharp7.cs:141:50:141:50 | 0 | CSharp7.cs:141:26:141:50 | ... ? ... : ... | | CSharp7.cs:143:20:143:20 | x | CSharp7.cs:143:29:143:29 | access to parameter x | -| CSharp7.cs:143:26:143:30 | call to local function f6 | CSharp7.cs:143:9:143:31 | return | +| CSharp7.cs:143:26:143:30 | call to local function f6 | CSharp7.cs:143:9:143:31 | return f7 | | CSharp7.cs:147:24:147:24 | x | CSharp7.cs:147:33:147:33 | access to parameter x | -| CSharp7.cs:147:30:147:34 | call to local function f7 | CSharp7.cs:147:13:147:35 | return | -| CSharp7.cs:148:20:148:24 | call to local function f9 | CSharp7.cs:145:9:149:9 | return | -| CSharp7.cs:152:25:152:25 | 0 | CSharp7.cs:152:13:152:26 | return | -| CSharp7.cs:155:16:155:20 | call to local function f1 | CSharp7.cs:129:9:129:12 | return | -| CSharp7.cs:160:23:160:23 | 1 | CSharp7.cs:160:9:160:24 | return | +| CSharp7.cs:147:30:147:34 | call to local function f7 | CSharp7.cs:147:13:147:35 | return f9 | +| CSharp7.cs:148:20:148:24 | call to local function f9 | CSharp7.cs:145:9:149:9 | return f8 | +| CSharp7.cs:152:25:152:25 | 0 | CSharp7.cs:152:13:152:26 | return f9 | +| CSharp7.cs:155:16:155:20 | call to local function f1 | CSharp7.cs:129:9:129:12 | return Main | +| CSharp7.cs:160:23:160:23 | 1 | CSharp7.cs:160:9:160:24 | return f | | CSharp7.cs:161:18:161:18 | t | CSharp7.cs:161:24:161:24 | access to parameter t | -| CSharp7.cs:161:24:161:24 | access to parameter t | CSharp7.cs:161:9:161:25 | return | +| CSharp7.cs:161:24:161:24 | access to parameter t | CSharp7.cs:161:9:161:25 | return g | | CSharp7.cs:163:26:163:26 | u | CSharp7.cs:167:22:167:22 | access to parameter u | -| CSharp7.cs:165:25:165:30 | call to local function f | CSharp7.cs:165:13:165:31 | return | -| CSharp7.cs:167:20:167:23 | call to local function g | CSharp7.cs:163:9:168:9 | return | +| CSharp7.cs:165:25:165:30 | call to local function f | CSharp7.cs:165:13:165:31 | return f2 | +| CSharp7.cs:167:20:167:23 | call to local function g | CSharp7.cs:163:9:168:9 | return h | | CSharp7.cs:176:16:176:30 | SSA def(src) | CSharp7.cs:181:23:181:25 | access to local variable src | | CSharp7.cs:176:22:176:30 | "tainted" | CSharp7.cs:176:16:176:30 | SSA def(src) | | CSharp7.cs:177:25:177:25 | s | CSharp7.cs:177:33:177:33 | access to parameter s | | CSharp7.cs:177:31:177:34 | call to local function g | CSharp7.cs:177:31:177:39 | ... + ... | -| CSharp7.cs:177:31:177:39 | ... + ... | CSharp7.cs:177:9:177:40 | return | +| CSharp7.cs:177:31:177:39 | ... + ... | CSharp7.cs:177:9:177:40 | return f | | CSharp7.cs:177:38:177:39 | "" | CSharp7.cs:177:31:177:39 | ... + ... | | CSharp7.cs:178:25:178:25 | s | CSharp7.cs:178:31:178:31 | access to parameter s | -| CSharp7.cs:178:31:178:31 | access to parameter s | CSharp7.cs:178:9:178:32 | return | +| CSharp7.cs:178:31:178:31 | access to parameter s | CSharp7.cs:178:9:178:32 | return g | | CSharp7.cs:179:25:179:25 | s | CSharp7.cs:179:37:179:37 | access to parameter s | -| CSharp7.cs:179:37:179:37 | access to parameter s | CSharp7.cs:179:9:179:40 | return | +| CSharp7.cs:179:37:179:37 | access to parameter s | CSharp7.cs:179:9:179:40 | return h | | CSharp7.cs:181:23:181:25 | access to local variable src | CSharp7.cs:182:23:182:25 | access to local variable src | | CSharp7.cs:182:23:182:25 | access to local variable src | CSharp7.cs:183:23:183:25 | access to local variable src | | CSharp7.cs:191:13:191:18 | SSA def(v1) | CSharp7.cs:192:26:192:27 | access to local variable v1 | @@ -156,11 +156,11 @@ | CSharp7.cs:199:33:199:34 | access to local variable r1 | CSharp7.cs:200:16:200:17 | access to local variable r1 | | CSharp7.cs:203:24:203:24 | p | CSharp7.cs:206:20:206:20 | access to parameter p | | CSharp7.cs:205:28:205:28 | q | CSharp7.cs:205:44:205:44 | access to parameter q | -| CSharp7.cs:205:40:205:44 | ref ... | CSharp7.cs:205:9:205:47 | return | -| CSharp7.cs:206:16:206:20 | ref ... | CSharp7.cs:203:13:203:14 | return | -| CSharp7.cs:216:13:216:17 | false | CSharp7.cs:214:30:214:30 | return (out/ref) | +| CSharp7.cs:205:40:205:44 | ref ... | CSharp7.cs:205:9:205:47 | return F3 | +| CSharp7.cs:206:16:206:20 | ref ... | CSharp7.cs:203:13:203:14 | return F2 | +| CSharp7.cs:216:13:216:17 | false | CSharp7.cs:214:30:214:30 | return (out/ref) f | | CSharp7.cs:216:13:216:17 | false | CSharp7.cs:216:9:216:17 | SSA def(x) | -| CSharp7.cs:217:16:217:23 | (..., ...) | CSharp7.cs:214:19:214:19 | return | +| CSharp7.cs:217:16:217:23 | (..., ...) | CSharp7.cs:214:19:214:19 | return f | | CSharp7.cs:217:17:217:17 | 0 | CSharp7.cs:217:16:217:23 | (..., ...) | | CSharp7.cs:217:20:217:22 | 0 | CSharp7.cs:217:16:217:23 | (..., ...) | | CSharp7.cs:233:16:233:23 | SSA def(o) | CSharp7.cs:234:13:234:13 | access to local variable o | @@ -211,7 +211,7 @@ | CSharp7.cs:284:20:284:62 | call to method Select | CSharp7.cs:284:13:284:62 | SSA def(list) | | CSharp7.cs:284:32:284:35 | item | CSharp7.cs:284:41:284:44 | access to parameter item | | CSharp7.cs:284:32:284:61 | [implicit call] (...) => ... | CSharp7.cs:284:20:284:62 | call to method Select | -| CSharp7.cs:284:40:284:61 | (..., ...) | CSharp7.cs:284:32:284:61 | return | +| CSharp7.cs:284:40:284:61 | (..., ...) | CSharp7.cs:284:32:284:61 | return (...) => ... | | CSharp7.cs:284:41:284:44 | access to parameter item | CSharp7.cs:284:51:284:54 | access to parameter item | | CSharp7.cs:284:41:284:48 | access to property Key | CSharp7.cs:284:40:284:61 | (..., ...) | | CSharp7.cs:284:51:284:54 | access to parameter item | CSharp7.cs:284:51:284:60 | access to property Value | diff --git a/csharp/ql/test/library-tests/csharp7/TaintReaches.expected b/csharp/ql/test/library-tests/csharp7/TaintReaches.expected index 4ffde6f4d13b..e6b0af63f14e 100644 --- a/csharp/ql/test/library-tests/csharp7/TaintReaches.expected +++ b/csharp/ql/test/library-tests/csharp7/TaintReaches.expected @@ -1,4 +1,4 @@ -| CSharp7.cs:41:13:41:21 | "tainted" | CSharp7.cs:39:23:39:23 | return (out/ref) | +| CSharp7.cs:41:13:41:21 | "tainted" | CSharp7.cs:39:23:39:23 | return (out/ref) F | | CSharp7.cs:41:13:41:21 | "tainted" | CSharp7.cs:41:9:41:21 | SSA def(x) | | CSharp7.cs:79:23:79:24 | "" | CSharp7.cs:79:22:79:28 | (..., ...) | | CSharp7.cs:89:19:89:27 | "tainted" | CSharp7.cs:89:13:89:34 | SSA def(t1) | @@ -30,7 +30,7 @@ | CSharp7.cs:176:22:176:30 | "tainted" | CSharp7.cs:181:23:181:25 | access to local variable src | | CSharp7.cs:176:22:176:30 | "tainted" | CSharp7.cs:182:23:182:25 | access to local variable src | | CSharp7.cs:176:22:176:30 | "tainted" | CSharp7.cs:183:23:183:25 | access to local variable src | -| CSharp7.cs:177:38:177:39 | "" | CSharp7.cs:177:9:177:40 | return | +| CSharp7.cs:177:38:177:39 | "" | CSharp7.cs:177:9:177:40 | return f | | CSharp7.cs:177:38:177:39 | "" | CSharp7.cs:177:31:177:39 | ... + ... | | CSharp7.cs:236:33:236:36 | "int " | CSharp7.cs:236:31:236:41 | $"..." | | CSharp7.cs:240:33:240:39 | "string " | CSharp7.cs:240:31:240:44 | $"..." | diff --git a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected index da4987a5fe59..4b897b1fe098 100644 --- a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected @@ -137,8 +137,8 @@ edges | GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | GlobalDataFlow.cs:153:15:153:19 | access to local variable sink7 | | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | GlobalDataFlow.cs:156:15:156:19 | access to local variable sink8 | | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | GlobalDataFlow.cs:160:15:160:20 | access to local variable sink23 | -| GlobalDataFlow.cs:175:29:175:48 | return | GlobalDataFlow.cs:176:21:176:26 | delegate call | -| GlobalDataFlow.cs:175:35:175:48 | "taint source" | GlobalDataFlow.cs:175:29:175:48 | return | +| GlobalDataFlow.cs:175:29:175:48 | return (...) => ... | GlobalDataFlow.cs:176:21:176:26 | delegate call | +| GlobalDataFlow.cs:175:35:175:48 | "taint source" | GlobalDataFlow.cs:175:29:175:48 | return (...) => ... | | GlobalDataFlow.cs:176:21:176:26 | delegate call | GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | GlobalDataFlow.cs:186:15:186:20 | access to local variable sink10 | | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | GlobalDataFlow.cs:194:15:194:20 | access to local variable sink19 | @@ -154,13 +154,13 @@ edges | GlobalDataFlow.cs:251:26:251:35 | sinkParam5 | GlobalDataFlow.cs:253:15:253:24 | access to parameter sinkParam5 | | GlobalDataFlow.cs:256:26:256:35 | sinkParam6 | GlobalDataFlow.cs:258:15:258:24 | access to parameter sinkParam6 | | GlobalDataFlow.cs:261:26:261:35 | sinkParam7 | GlobalDataFlow.cs:263:15:263:24 | access to parameter sinkParam7 | -| GlobalDataFlow.cs:311:12:311:14 | return | GlobalDataFlow.cs:149:21:149:25 | call to method Out | -| GlobalDataFlow.cs:311:12:311:14 | return | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | -| GlobalDataFlow.cs:313:16:313:29 | "taint source" | GlobalDataFlow.cs:311:12:311:14 | return | -| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | -| GlobalDataFlow.cs:318:13:318:26 | "taint source" | GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | -| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | -| GlobalDataFlow.cs:323:13:323:26 | "taint source" | GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | +| GlobalDataFlow.cs:311:12:311:14 | return Out | GlobalDataFlow.cs:149:21:149:25 | call to method Out | +| GlobalDataFlow.cs:311:12:311:14 | return Out | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | +| GlobalDataFlow.cs:313:16:313:29 | "taint source" | GlobalDataFlow.cs:311:12:311:14 | return Out | +| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) OutOut | GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | +| GlobalDataFlow.cs:318:13:318:26 | "taint source" | GlobalDataFlow.cs:316:28:316:28 | return (out/ref) OutOut | +| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) OutRef | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | +| GlobalDataFlow.cs:323:13:323:26 | "taint source" | GlobalDataFlow.cs:321:28:321:28 | return (out/ref) OutRef | | GlobalDataFlow.cs:354:41:354:41 | x | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | | GlobalDataFlow.cs:354:41:354:41 | x | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | GlobalDataFlow.cs:53:15:53:15 | x | @@ -171,12 +171,12 @@ edges | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:56:37:56:37 | x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:251:26:251:35 | sinkParam5 | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:256:26:256:35 | sinkParam6 | -| GlobalDataFlow.cs:373:19:373:30 | return | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | -| GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:373:19:373:30 | return | +| GlobalDataFlow.cs:373:19:373:30 | return TaintedParam | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | +| GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:373:19:373:30 | return TaintedParam | | GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | | GlobalDataFlow.cs:399:9:399:11 | value | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | -| GlobalDataFlow.cs:410:9:410:11 | return | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | -| GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:410:9:410:11 | return | +| GlobalDataFlow.cs:410:9:410:11 | return get_OutProperty | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | +| GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:410:9:410:11 | return get_OutProperty | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | @@ -275,7 +275,7 @@ nodes | GlobalDataFlow.cs:156:15:156:19 | access to local variable sink8 | | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | | GlobalDataFlow.cs:160:15:160:20 | access to local variable sink23 | -| GlobalDataFlow.cs:175:29:175:48 | return | +| GlobalDataFlow.cs:175:29:175:48 | return (...) => ... | | GlobalDataFlow.cs:175:35:175:48 | "taint source" | | GlobalDataFlow.cs:176:21:176:26 | delegate call | | GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | @@ -301,11 +301,11 @@ nodes | GlobalDataFlow.cs:258:15:258:24 | access to parameter sinkParam6 | | GlobalDataFlow.cs:261:26:261:35 | sinkParam7 | | GlobalDataFlow.cs:263:15:263:24 | access to parameter sinkParam7 | -| GlobalDataFlow.cs:311:12:311:14 | return | +| GlobalDataFlow.cs:311:12:311:14 | return Out | | GlobalDataFlow.cs:313:16:313:29 | "taint source" | -| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | +| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) OutOut | | GlobalDataFlow.cs:318:13:318:26 | "taint source" | -| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | +| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) OutRef | | GlobalDataFlow.cs:323:13:323:26 | "taint source" | | GlobalDataFlow.cs:354:41:354:41 | x | | GlobalDataFlow.cs:354:41:354:41 | x | @@ -317,12 +317,12 @@ nodes | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | -| GlobalDataFlow.cs:373:19:373:30 | return | +| GlobalDataFlow.cs:373:19:373:30 | return TaintedParam | | GlobalDataFlow.cs:373:39:373:45 | tainted | | GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | | GlobalDataFlow.cs:399:9:399:11 | value | | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | -| GlobalDataFlow.cs:410:9:410:11 | return | +| GlobalDataFlow.cs:410:9:410:11 | return get_OutProperty | | GlobalDataFlow.cs:410:22:410:35 | "taint source" | | Splitting.cs:3:28:3:34 | tainted | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | diff --git a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected index 2f4168a0f638..a81bbb23422d 100644 --- a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected @@ -161,8 +161,8 @@ edges | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | GlobalDataFlow.cs:156:15:156:19 | access to local variable sink8 | | GlobalDataFlow.cs:157:22:157:31 | call to method OutYield | GlobalDataFlow.cs:158:15:158:20 | access to local variable sink12 | | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | GlobalDataFlow.cs:160:15:160:20 | access to local variable sink23 | -| GlobalDataFlow.cs:175:29:175:48 | return | GlobalDataFlow.cs:176:21:176:26 | delegate call | -| GlobalDataFlow.cs:175:35:175:48 | "taint source" | GlobalDataFlow.cs:175:29:175:48 | return | +| GlobalDataFlow.cs:175:29:175:48 | return (...) => ... | GlobalDataFlow.cs:176:21:176:26 | delegate call | +| GlobalDataFlow.cs:175:35:175:48 | "taint source" | GlobalDataFlow.cs:175:29:175:48 | return (...) => ... | | GlobalDataFlow.cs:176:21:176:26 | delegate call | GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | GlobalDataFlow.cs:186:15:186:20 | access to local variable sink10 | | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | GlobalDataFlow.cs:194:15:194:20 | access to local variable sink19 | @@ -196,15 +196,15 @@ edges | GlobalDataFlow.cs:287:31:287:40 | sinkParam8 | GlobalDataFlow.cs:289:15:289:24 | access to parameter sinkParam8 | | GlobalDataFlow.cs:293:32:293:41 | sinkParam9 | GlobalDataFlow.cs:295:15:295:24 | access to parameter sinkParam9 | | GlobalDataFlow.cs:299:32:299:42 | sinkParam11 | GlobalDataFlow.cs:301:15:301:25 | access to parameter sinkParam11 | -| GlobalDataFlow.cs:311:12:311:14 | return | GlobalDataFlow.cs:149:21:149:25 | call to method Out | -| GlobalDataFlow.cs:311:12:311:14 | return | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | -| GlobalDataFlow.cs:313:16:313:29 | "taint source" | GlobalDataFlow.cs:311:12:311:14 | return | -| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | -| GlobalDataFlow.cs:318:13:318:26 | "taint source" | GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | -| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | -| GlobalDataFlow.cs:323:13:323:26 | "taint source" | GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | -| GlobalDataFlow.cs:326:25:326:32 | yield return | GlobalDataFlow.cs:157:22:157:31 | call to method OutYield | -| GlobalDataFlow.cs:329:22:329:35 | "taint source" | GlobalDataFlow.cs:326:25:326:32 | yield return | +| GlobalDataFlow.cs:311:12:311:14 | return Out | GlobalDataFlow.cs:149:21:149:25 | call to method Out | +| GlobalDataFlow.cs:311:12:311:14 | return Out | GlobalDataFlow.cs:185:39:185:41 | [implicit call] delegate creation of type Func | +| GlobalDataFlow.cs:313:16:313:29 | "taint source" | GlobalDataFlow.cs:311:12:311:14 | return Out | +| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) OutOut | GlobalDataFlow.cs:152:20:152:24 | SSA def(sink7) | +| GlobalDataFlow.cs:318:13:318:26 | "taint source" | GlobalDataFlow.cs:316:28:316:28 | return (out/ref) OutOut | +| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) OutRef | GlobalDataFlow.cs:155:20:155:24 | SSA def(sink8) | +| GlobalDataFlow.cs:323:13:323:26 | "taint source" | GlobalDataFlow.cs:321:28:321:28 | return (out/ref) OutRef | +| GlobalDataFlow.cs:326:25:326:32 | yield return OutYield | GlobalDataFlow.cs:157:22:157:31 | call to method OutYield | +| GlobalDataFlow.cs:329:22:329:35 | "taint source" | GlobalDataFlow.cs:326:25:326:32 | yield return OutYield | | GlobalDataFlow.cs:354:41:354:41 | x | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | | GlobalDataFlow.cs:354:41:354:41 | x | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | | GlobalDataFlow.cs:356:11:356:11 | access to parameter x | GlobalDataFlow.cs:53:15:53:15 | x | @@ -215,12 +215,12 @@ edges | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:56:37:56:37 | x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:251:26:251:35 | sinkParam5 | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | GlobalDataFlow.cs:256:26:256:35 | sinkParam6 | -| GlobalDataFlow.cs:373:19:373:30 | return | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | -| GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:373:19:373:30 | return | +| GlobalDataFlow.cs:373:19:373:30 | return TaintedParam | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | +| GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:373:19:373:30 | return TaintedParam | | GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | | GlobalDataFlow.cs:399:9:399:11 | value | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | -| GlobalDataFlow.cs:410:9:410:11 | return | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | -| GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:410:9:410:11 | return | +| GlobalDataFlow.cs:410:9:410:11 | return get_OutProperty | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty | +| GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:410:9:410:11 | return get_OutProperty | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted | | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | @@ -343,7 +343,7 @@ nodes | GlobalDataFlow.cs:158:15:158:20 | access to local variable sink12 | | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam | | GlobalDataFlow.cs:160:15:160:20 | access to local variable sink23 | -| GlobalDataFlow.cs:175:29:175:48 | return | +| GlobalDataFlow.cs:175:29:175:48 | return (...) => ... | | GlobalDataFlow.cs:175:35:175:48 | "taint source" | | GlobalDataFlow.cs:176:21:176:26 | delegate call | | GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | @@ -389,13 +389,13 @@ nodes | GlobalDataFlow.cs:295:15:295:24 | access to parameter sinkParam9 | | GlobalDataFlow.cs:299:32:299:42 | sinkParam11 | | GlobalDataFlow.cs:301:15:301:25 | access to parameter sinkParam11 | -| GlobalDataFlow.cs:311:12:311:14 | return | +| GlobalDataFlow.cs:311:12:311:14 | return Out | | GlobalDataFlow.cs:313:16:313:29 | "taint source" | -| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) | +| GlobalDataFlow.cs:316:28:316:28 | return (out/ref) OutOut | | GlobalDataFlow.cs:318:13:318:26 | "taint source" | -| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) | +| GlobalDataFlow.cs:321:28:321:28 | return (out/ref) OutRef | | GlobalDataFlow.cs:323:13:323:26 | "taint source" | -| GlobalDataFlow.cs:326:25:326:32 | yield return | +| GlobalDataFlow.cs:326:25:326:32 | yield return OutYield | | GlobalDataFlow.cs:329:22:329:35 | "taint source" | | GlobalDataFlow.cs:354:41:354:41 | x | | GlobalDataFlow.cs:354:41:354:41 | x | @@ -407,12 +407,12 @@ nodes | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | | GlobalDataFlow.cs:370:11:370:11 | access to parameter x | -| GlobalDataFlow.cs:373:19:373:30 | return | +| GlobalDataFlow.cs:373:19:373:30 | return TaintedParam | | GlobalDataFlow.cs:373:39:373:45 | tainted | | GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | | GlobalDataFlow.cs:399:9:399:11 | value | | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | -| GlobalDataFlow.cs:410:9:410:11 | return | +| GlobalDataFlow.cs:410:9:410:11 | return get_OutProperty | | GlobalDataFlow.cs:410:22:410:35 | "taint source" | | Splitting.cs:3:28:3:34 | tainted | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | diff --git a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 922a99229c08..ce40010d6806 100644 --- a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -14,11 +14,11 @@ | Capture.cs:58:21:58:21 | 1 | Capture.cs:58:17:58:21 | SSA def(i) | | Capture.cs:61:17:61:17 | 1 | Capture.cs:61:13:61:17 | SSA def(i) | | Capture.cs:63:9:63:17 | SSA call def(i) | Capture.cs:64:13:64:13 | access to local variable i | -| LocalDataFlow.cs:16:55:16:58 | null | LocalDataFlow.cs:16:42:16:44 | return | -| LocalDataFlow.cs:18:63:18:66 | null | LocalDataFlow.cs:18:50:18:52 | return | -| LocalDataFlow.cs:20:59:20:62 | null | LocalDataFlow.cs:20:46:20:48 | return | -| LocalDataFlow.cs:22:45:22:48 | null | LocalDataFlow.cs:22:32:22:34 | return | -| LocalDataFlow.cs:24:39:24:42 | null | LocalDataFlow.cs:24:26:24:28 | return | +| LocalDataFlow.cs:16:55:16:58 | null | LocalDataFlow.cs:16:42:16:44 | return get_Item | +| LocalDataFlow.cs:18:63:18:66 | null | LocalDataFlow.cs:18:50:18:52 | return get_QueryString | +| LocalDataFlow.cs:20:59:20:62 | null | LocalDataFlow.cs:20:46:20:48 | return get_Headers | +| LocalDataFlow.cs:22:45:22:48 | null | LocalDataFlow.cs:22:32:22:34 | return get_RawUrl | +| LocalDataFlow.cs:24:39:24:42 | null | LocalDataFlow.cs:24:26:24:28 | return get_Url | | LocalDataFlow.cs:49:30:49:30 | b | LocalDataFlow.cs:96:21:96:21 | access to parameter b | | LocalDataFlow.cs:52:13:52:34 | SSA def(sink0) | LocalDataFlow.cs:53:15:53:19 | access to local variable sink0 | | LocalDataFlow.cs:52:21:52:34 | "taint source" | LocalDataFlow.cs:52:13:52:34 | SSA def(sink0) | @@ -112,14 +112,14 @@ | LocalDataFlow.cs:136:22:136:55 | call to method First | LocalDataFlow.cs:136:13:136:55 | SSA def(sink14) | | LocalDataFlow.cs:136:35:136:35 | x | LocalDataFlow.cs:136:40:136:40 | access to parameter x | | LocalDataFlow.cs:136:40:136:40 | access to parameter x | LocalDataFlow.cs:136:40:136:46 | access to property Value | -| LocalDataFlow.cs:136:40:136:54 | ... != ... | LocalDataFlow.cs:136:35:136:54 | return | +| LocalDataFlow.cs:136:40:136:54 | ... != ... | LocalDataFlow.cs:136:35:136:54 | return (...) => ... | | LocalDataFlow.cs:140:9:140:55 | SSA def(nonSink3) | LocalDataFlow.cs:206:33:206:40 | access to local variable nonSink3 | | LocalDataFlow.cs:140:20:140:27 | access to local variable nonSink1 | LocalDataFlow.cs:141:15:141:22 | access to local variable nonSink1 | | LocalDataFlow.cs:140:20:140:55 | (...) ... | LocalDataFlow.cs:140:9:140:55 | SSA def(nonSink3) | | LocalDataFlow.cs:140:20:140:55 | call to method First | LocalDataFlow.cs:140:20:140:55 | (...) ... | | LocalDataFlow.cs:140:35:140:35 | x | LocalDataFlow.cs:140:40:140:40 | access to parameter x | | LocalDataFlow.cs:140:40:140:40 | access to parameter x | LocalDataFlow.cs:140:40:140:46 | access to property Value | -| LocalDataFlow.cs:140:40:140:54 | ... != ... | LocalDataFlow.cs:140:35:140:54 | return | +| LocalDataFlow.cs:140:40:140:54 | ... != ... | LocalDataFlow.cs:140:35:140:54 | return (...) => ... | | LocalDataFlow.cs:141:15:141:22 | access to local variable nonSink1 | LocalDataFlow.cs:214:20:214:27 | access to local variable nonSink1 | | LocalDataFlow.cs:144:13:144:39 | SSA def(sink15) | LocalDataFlow.cs:145:15:145:20 | access to local variable sink15 | | LocalDataFlow.cs:144:22:144:39 | call to method Parse | LocalDataFlow.cs:144:13:144:39 | SSA def(sink15) | @@ -317,7 +317,7 @@ | LocalDataFlow.cs:303:13:303:59 | SSA def(sink42) | LocalDataFlow.cs:304:15:304:20 | access to local variable sink42 | | LocalDataFlow.cs:303:22:303:59 | object creation of type Lazy | LocalDataFlow.cs:303:13:303:59 | SSA def(sink42) | | LocalDataFlow.cs:303:39:303:58 | [implicit call] (...) => ... | LocalDataFlow.cs:303:22:303:59 | object creation of type Lazy | -| LocalDataFlow.cs:303:45:303:58 | "taint source" | LocalDataFlow.cs:303:39:303:58 | return | +| LocalDataFlow.cs:303:45:303:58 | "taint source" | LocalDataFlow.cs:303:39:303:58 | return (...) => ... | | LocalDataFlow.cs:304:15:304:20 | access to local variable sink42 | LocalDataFlow.cs:305:22:305:27 | access to local variable sink42 | | LocalDataFlow.cs:305:13:305:33 | SSA def(sink43) | LocalDataFlow.cs:306:15:306:20 | access to local variable sink43 | | LocalDataFlow.cs:305:22:305:27 | access to local variable sink42 | LocalDataFlow.cs:305:22:305:33 | access to property Value | @@ -332,7 +332,7 @@ | LocalDataFlow.cs:313:9:313:46 | SSA def(nonSink12) | LocalDataFlow.cs:314:15:314:23 | access to local variable nonSink12 | | LocalDataFlow.cs:313:21:313:46 | object creation of type Lazy | LocalDataFlow.cs:313:9:313:46 | SSA def(nonSink12) | | LocalDataFlow.cs:313:38:313:45 | [implicit call] (...) => ... | LocalDataFlow.cs:313:21:313:46 | object creation of type Lazy | -| LocalDataFlow.cs:313:44:313:45 | "" | LocalDataFlow.cs:313:38:313:45 | return | +| LocalDataFlow.cs:313:44:313:45 | "" | LocalDataFlow.cs:313:38:313:45 | return (...) => ... | | LocalDataFlow.cs:314:15:314:23 | access to local variable nonSink12 | LocalDataFlow.cs:315:20:315:28 | access to local variable nonSink12 | | LocalDataFlow.cs:315:9:315:34 | SSA def(nonSink0) | LocalDataFlow.cs:316:15:316:22 | access to local variable nonSink0 | | LocalDataFlow.cs:315:20:315:28 | access to local variable nonSink12 | LocalDataFlow.cs:315:20:315:34 | access to property Value | @@ -427,7 +427,7 @@ | LocalDataFlow.cs:391:13:391:51 | SSA def(sink67) | LocalDataFlow.cs:392:15:392:20 | access to local variable sink67 | | LocalDataFlow.cs:391:22:391:51 | call to method Run | LocalDataFlow.cs:391:13:391:51 | SSA def(sink67) | | LocalDataFlow.cs:391:31:391:50 | [implicit call] (...) => ... | LocalDataFlow.cs:391:22:391:51 | call to method Run | -| LocalDataFlow.cs:391:37:391:50 | "taint source" | LocalDataFlow.cs:391:31:391:50 | return | +| LocalDataFlow.cs:391:37:391:50 | "taint source" | LocalDataFlow.cs:391:31:391:50 | return (...) => ... | | LocalDataFlow.cs:392:15:392:20 | access to local variable sink67 | LocalDataFlow.cs:393:28:393:33 | access to local variable sink67 | | LocalDataFlow.cs:393:13:393:33 | SSA def(sink68) | LocalDataFlow.cs:394:15:394:20 | access to local variable sink68 | | LocalDataFlow.cs:393:22:393:33 | await ... | LocalDataFlow.cs:393:13:393:33 | SSA def(sink68) | @@ -435,7 +435,7 @@ | LocalDataFlow.cs:397:13:397:42 | SSA def(nonSink21) | LocalDataFlow.cs:398:15:398:23 | access to local variable nonSink21 | | LocalDataFlow.cs:397:25:397:42 | call to method Run | LocalDataFlow.cs:397:13:397:42 | SSA def(nonSink21) | | LocalDataFlow.cs:397:34:397:41 | [implicit call] (...) => ... | LocalDataFlow.cs:397:25:397:42 | call to method Run | -| LocalDataFlow.cs:397:40:397:41 | "" | LocalDataFlow.cs:397:34:397:41 | return | +| LocalDataFlow.cs:397:40:397:41 | "" | LocalDataFlow.cs:397:34:397:41 | return (...) => ... | | LocalDataFlow.cs:398:15:398:23 | access to local variable nonSink21 | LocalDataFlow.cs:399:26:399:34 | access to local variable nonSink21 | | LocalDataFlow.cs:399:9:399:34 | SSA def(nonSink0) | LocalDataFlow.cs:400:15:400:22 | access to local variable nonSink0 | | LocalDataFlow.cs:399:20:399:34 | await ... | LocalDataFlow.cs:399:9:399:34 | SSA def(nonSink0) | @@ -464,9 +464,9 @@ | LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) | LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 | | LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | LocalDataFlow.cs:438:23:438:31 | access to local variable nonSink17 | -| LocalDataFlow.cs:447:37:447:38 | "" | LocalDataFlow.cs:447:12:447:24 | return | -| LocalDataFlow.cs:449:40:449:41 | "" | LocalDataFlow.cs:449:12:449:27 | return | -| LocalDataFlow.cs:458:41:458:45 | access to field anInt | LocalDataFlow.cs:458:28:458:30 | return | +| LocalDataFlow.cs:447:37:447:38 | "" | LocalDataFlow.cs:447:12:447:24 | return TaintedMethod | +| LocalDataFlow.cs:449:40:449:41 | "" | LocalDataFlow.cs:449:12:449:27 | return NonTaintedMethod | +| LocalDataFlow.cs:458:41:458:45 | access to field anInt | LocalDataFlow.cs:458:28:458:30 | return get_AnInt | | LocalDataFlow.cs:458:50:458:52 | value | LocalDataFlow.cs:458:64:458:68 | access to parameter value | | LocalDataFlow.cs:464:41:464:47 | tainted | LocalDataFlow.cs:466:15:466:21 | access to parameter tainted | | LocalDataFlow.cs:469:44:469:53 | nonTainted | LocalDataFlow.cs:471:15:471:24 | access to parameter nonTainted | @@ -638,10 +638,10 @@ | SSA.cs:146:13:146:13 | access to parameter t | SSA.cs:146:13:146:13 | (...) ... | | SSA.cs:146:13:146:13 | access to parameter t | SSA.cs:149:17:149:17 | access to parameter t | | SSA.cs:147:13:147:26 | SSA def(t) | SSA.cs:144:17:144:26 | SSA phi(t) | -| SSA.cs:147:17:147:26 | default(...) | SSA.cs:144:34:144:34 | return (out/ref) | +| SSA.cs:147:17:147:26 | default(...) | SSA.cs:144:34:144:34 | return (out/ref) Certain | | SSA.cs:147:17:147:26 | default(...) | SSA.cs:147:13:147:26 | SSA def(t) | | SSA.cs:149:13:149:17 | SSA def(t) | SSA.cs:144:17:144:26 | SSA phi(t) | -| SSA.cs:149:17:149:17 | access to parameter t | SSA.cs:144:34:144:34 | return (out/ref) | +| SSA.cs:149:17:149:17 | access to parameter t | SSA.cs:144:34:144:34 | return (out/ref) Certain | | SSA.cs:149:17:149:17 | access to parameter t | SSA.cs:149:13:149:17 | SSA def(t) | | SSA.cs:152:36:152:36 | t | SSA.cs:154:13:154:13 | access to parameter t | | SSA.cs:154:13:154:13 | access to parameter t | SSA.cs:152:17:152:28 | SSA phi(t) | diff --git a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected index 6ad6a3ba0baf..d3444e6ac82e 100644 --- a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected @@ -14,11 +14,11 @@ | Capture.cs:58:21:58:21 | 1 | Capture.cs:58:17:58:21 | SSA def(i) | | Capture.cs:61:17:61:17 | 1 | Capture.cs:61:13:61:17 | SSA def(i) | | Capture.cs:63:9:63:17 | SSA call def(i) | Capture.cs:64:13:64:13 | access to local variable i | -| LocalDataFlow.cs:16:55:16:58 | null | LocalDataFlow.cs:16:42:16:44 | return | -| LocalDataFlow.cs:18:63:18:66 | null | LocalDataFlow.cs:18:50:18:52 | return | -| LocalDataFlow.cs:20:59:20:62 | null | LocalDataFlow.cs:20:46:20:48 | return | -| LocalDataFlow.cs:22:45:22:48 | null | LocalDataFlow.cs:22:32:22:34 | return | -| LocalDataFlow.cs:24:39:24:42 | null | LocalDataFlow.cs:24:26:24:28 | return | +| LocalDataFlow.cs:16:55:16:58 | null | LocalDataFlow.cs:16:42:16:44 | return get_Item | +| LocalDataFlow.cs:18:63:18:66 | null | LocalDataFlow.cs:18:50:18:52 | return get_QueryString | +| LocalDataFlow.cs:20:59:20:62 | null | LocalDataFlow.cs:20:46:20:48 | return get_Headers | +| LocalDataFlow.cs:22:45:22:48 | null | LocalDataFlow.cs:22:32:22:34 | return get_RawUrl | +| LocalDataFlow.cs:24:39:24:42 | null | LocalDataFlow.cs:24:26:24:28 | return get_Url | | LocalDataFlow.cs:49:30:49:30 | b | LocalDataFlow.cs:96:21:96:21 | access to parameter b | | LocalDataFlow.cs:52:13:52:34 | SSA def(sink0) | LocalDataFlow.cs:53:15:53:19 | access to local variable sink0 | | LocalDataFlow.cs:52:21:52:34 | "taint source" | LocalDataFlow.cs:52:13:52:34 | SSA def(sink0) | @@ -136,7 +136,7 @@ | LocalDataFlow.cs:136:35:136:35 | x | LocalDataFlow.cs:136:40:136:40 | access to parameter x | | LocalDataFlow.cs:136:40:136:40 | access to parameter x | LocalDataFlow.cs:136:40:136:46 | access to property Value | | LocalDataFlow.cs:136:40:136:46 | access to property Value | LocalDataFlow.cs:136:40:136:54 | ... != ... | -| LocalDataFlow.cs:136:40:136:54 | ... != ... | LocalDataFlow.cs:136:35:136:54 | return | +| LocalDataFlow.cs:136:40:136:54 | ... != ... | LocalDataFlow.cs:136:35:136:54 | return (...) => ... | | LocalDataFlow.cs:140:9:140:55 | SSA def(nonSink3) | LocalDataFlow.cs:206:33:206:40 | access to local variable nonSink3 | | LocalDataFlow.cs:140:20:140:27 | access to local variable nonSink1 | LocalDataFlow.cs:140:20:140:55 | call to method First | | LocalDataFlow.cs:140:20:140:27 | access to local variable nonSink1 | LocalDataFlow.cs:141:15:141:22 | access to local variable nonSink1 | @@ -145,7 +145,7 @@ | LocalDataFlow.cs:140:35:140:35 | x | LocalDataFlow.cs:140:40:140:40 | access to parameter x | | LocalDataFlow.cs:140:40:140:40 | access to parameter x | LocalDataFlow.cs:140:40:140:46 | access to property Value | | LocalDataFlow.cs:140:40:140:46 | access to property Value | LocalDataFlow.cs:140:40:140:54 | ... != ... | -| LocalDataFlow.cs:140:40:140:54 | ... != ... | LocalDataFlow.cs:140:35:140:54 | return | +| LocalDataFlow.cs:140:40:140:54 | ... != ... | LocalDataFlow.cs:140:35:140:54 | return (...) => ... | | LocalDataFlow.cs:141:15:141:22 | access to local variable nonSink1 | LocalDataFlow.cs:214:20:214:27 | access to local variable nonSink1 | | LocalDataFlow.cs:144:13:144:39 | SSA def(sink15) | LocalDataFlow.cs:145:15:145:20 | access to local variable sink15 | | LocalDataFlow.cs:144:22:144:39 | call to method Parse | LocalDataFlow.cs:144:13:144:39 | SSA def(sink15) | @@ -433,7 +433,7 @@ | LocalDataFlow.cs:303:13:303:59 | SSA def(sink42) | LocalDataFlow.cs:304:15:304:20 | access to local variable sink42 | | LocalDataFlow.cs:303:22:303:59 | object creation of type Lazy | LocalDataFlow.cs:303:13:303:59 | SSA def(sink42) | | LocalDataFlow.cs:303:39:303:58 | [implicit call] (...) => ... | LocalDataFlow.cs:303:22:303:59 | object creation of type Lazy | -| LocalDataFlow.cs:303:45:303:58 | "taint source" | LocalDataFlow.cs:303:39:303:58 | return | +| LocalDataFlow.cs:303:45:303:58 | "taint source" | LocalDataFlow.cs:303:39:303:58 | return (...) => ... | | LocalDataFlow.cs:304:15:304:20 | access to local variable sink42 | LocalDataFlow.cs:305:22:305:27 | access to local variable sink42 | | LocalDataFlow.cs:305:13:305:33 | SSA def(sink43) | LocalDataFlow.cs:306:15:306:20 | access to local variable sink43 | | LocalDataFlow.cs:305:22:305:27 | access to local variable sink42 | LocalDataFlow.cs:305:22:305:33 | access to property Value | @@ -448,7 +448,7 @@ | LocalDataFlow.cs:313:9:313:46 | SSA def(nonSink12) | LocalDataFlow.cs:314:15:314:23 | access to local variable nonSink12 | | LocalDataFlow.cs:313:21:313:46 | object creation of type Lazy | LocalDataFlow.cs:313:9:313:46 | SSA def(nonSink12) | | LocalDataFlow.cs:313:38:313:45 | [implicit call] (...) => ... | LocalDataFlow.cs:313:21:313:46 | object creation of type Lazy | -| LocalDataFlow.cs:313:44:313:45 | "" | LocalDataFlow.cs:313:38:313:45 | return | +| LocalDataFlow.cs:313:44:313:45 | "" | LocalDataFlow.cs:313:38:313:45 | return (...) => ... | | LocalDataFlow.cs:314:15:314:23 | access to local variable nonSink12 | LocalDataFlow.cs:315:20:315:28 | access to local variable nonSink12 | | LocalDataFlow.cs:315:9:315:34 | SSA def(nonSink0) | LocalDataFlow.cs:316:15:316:22 | access to local variable nonSink0 | | LocalDataFlow.cs:315:20:315:28 | access to local variable nonSink12 | LocalDataFlow.cs:315:20:315:34 | access to property Value | @@ -565,7 +565,7 @@ | LocalDataFlow.cs:391:13:391:51 | SSA def(sink67) | LocalDataFlow.cs:392:15:392:20 | access to local variable sink67 | | LocalDataFlow.cs:391:22:391:51 | call to method Run | LocalDataFlow.cs:391:13:391:51 | SSA def(sink67) | | LocalDataFlow.cs:391:31:391:50 | [implicit call] (...) => ... | LocalDataFlow.cs:391:22:391:51 | call to method Run | -| LocalDataFlow.cs:391:37:391:50 | "taint source" | LocalDataFlow.cs:391:31:391:50 | return | +| LocalDataFlow.cs:391:37:391:50 | "taint source" | LocalDataFlow.cs:391:31:391:50 | return (...) => ... | | LocalDataFlow.cs:392:15:392:20 | access to local variable sink67 | LocalDataFlow.cs:393:28:393:33 | access to local variable sink67 | | LocalDataFlow.cs:393:13:393:33 | SSA def(sink68) | LocalDataFlow.cs:394:15:394:20 | access to local variable sink68 | | LocalDataFlow.cs:393:22:393:33 | await ... | LocalDataFlow.cs:393:13:393:33 | SSA def(sink68) | @@ -573,7 +573,7 @@ | LocalDataFlow.cs:397:13:397:42 | SSA def(nonSink21) | LocalDataFlow.cs:398:15:398:23 | access to local variable nonSink21 | | LocalDataFlow.cs:397:25:397:42 | call to method Run | LocalDataFlow.cs:397:13:397:42 | SSA def(nonSink21) | | LocalDataFlow.cs:397:34:397:41 | [implicit call] (...) => ... | LocalDataFlow.cs:397:25:397:42 | call to method Run | -| LocalDataFlow.cs:397:40:397:41 | "" | LocalDataFlow.cs:397:34:397:41 | return | +| LocalDataFlow.cs:397:40:397:41 | "" | LocalDataFlow.cs:397:34:397:41 | return (...) => ... | | LocalDataFlow.cs:398:15:398:23 | access to local variable nonSink21 | LocalDataFlow.cs:399:26:399:34 | access to local variable nonSink21 | | LocalDataFlow.cs:399:9:399:34 | SSA def(nonSink0) | LocalDataFlow.cs:400:15:400:22 | access to local variable nonSink0 | | LocalDataFlow.cs:399:20:399:34 | await ... | LocalDataFlow.cs:399:9:399:34 | SSA def(nonSink0) | @@ -606,9 +606,9 @@ | LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) | LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 | | LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | LocalDataFlow.cs:438:23:438:31 | access to local variable nonSink17 | -| LocalDataFlow.cs:447:37:447:38 | "" | LocalDataFlow.cs:447:12:447:24 | return | -| LocalDataFlow.cs:449:40:449:41 | "" | LocalDataFlow.cs:449:12:449:27 | return | -| LocalDataFlow.cs:458:41:458:45 | access to field anInt | LocalDataFlow.cs:458:28:458:30 | return | +| LocalDataFlow.cs:447:37:447:38 | "" | LocalDataFlow.cs:447:12:447:24 | return TaintedMethod | +| LocalDataFlow.cs:449:40:449:41 | "" | LocalDataFlow.cs:449:12:449:27 | return NonTaintedMethod | +| LocalDataFlow.cs:458:41:458:45 | access to field anInt | LocalDataFlow.cs:458:28:458:30 | return get_AnInt | | LocalDataFlow.cs:458:50:458:52 | value | LocalDataFlow.cs:458:64:458:68 | access to parameter value | | LocalDataFlow.cs:464:41:464:47 | tainted | LocalDataFlow.cs:466:15:466:21 | access to parameter tainted | | LocalDataFlow.cs:469:44:469:53 | nonTainted | LocalDataFlow.cs:471:15:471:24 | access to parameter nonTainted | @@ -795,10 +795,10 @@ | SSA.cs:146:13:146:13 | access to parameter t | SSA.cs:146:13:146:13 | (...) ... | | SSA.cs:146:13:146:13 | access to parameter t | SSA.cs:149:17:149:17 | access to parameter t | | SSA.cs:147:13:147:26 | SSA def(t) | SSA.cs:144:17:144:26 | SSA phi(t) | -| SSA.cs:147:17:147:26 | default(...) | SSA.cs:144:34:144:34 | return (out/ref) | +| SSA.cs:147:17:147:26 | default(...) | SSA.cs:144:34:144:34 | return (out/ref) Certain | | SSA.cs:147:17:147:26 | default(...) | SSA.cs:147:13:147:26 | SSA def(t) | | SSA.cs:149:13:149:17 | SSA def(t) | SSA.cs:144:17:144:26 | SSA phi(t) | -| SSA.cs:149:17:149:17 | access to parameter t | SSA.cs:144:34:144:34 | return (out/ref) | +| SSA.cs:149:17:149:17 | access to parameter t | SSA.cs:144:34:144:34 | return (out/ref) Certain | | SSA.cs:149:17:149:17 | access to parameter t | SSA.cs:149:13:149:17 | SSA def(t) | | SSA.cs:152:36:152:36 | t | SSA.cs:154:13:154:13 | access to parameter t | | SSA.cs:154:13:154:13 | (...) ... | SSA.cs:154:13:154:21 | ... == ... | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected index 9cd83abf87ca..c4addd5efdec 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected @@ -1,29 +1,29 @@ edges -| InsecureRandomness.cs:21:26:21:45 | return | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | -| InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:21:26:21:45 | return | +| InsecureRandomness.cs:21:26:21:45 | return InsecureRandomString | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | +| InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:21:26:21:45 | return InsecureRandomString | | InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:29:27:29:61 | call to method GetString | | InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:31:16:31:32 | call to method ToString | -| InsecureRandomness.cs:29:27:29:61 | call to method GetString | InsecureRandomness.cs:21:26:21:45 | return | +| InsecureRandomness.cs:29:27:29:61 | call to method GetString | InsecureRandomness.cs:21:26:21:45 | return InsecureRandomString | | InsecureRandomness.cs:29:27:29:61 | call to method GetString | InsecureRandomness.cs:31:16:31:32 | call to method ToString | -| InsecureRandomness.cs:31:16:31:32 | call to method ToString | InsecureRandomness.cs:21:26:21:45 | return | -| InsecureRandomness.cs:53:26:53:58 | return | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | -| InsecureRandomness.cs:60:31:60:39 | call to method Next | InsecureRandomness.cs:53:26:53:58 | return | +| InsecureRandomness.cs:31:16:31:32 | call to method ToString | InsecureRandomness.cs:21:26:21:45 | return InsecureRandomString | +| InsecureRandomness.cs:53:26:53:58 | return InsecureRandomStringFromSelection | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | +| InsecureRandomness.cs:60:31:60:39 | call to method Next | InsecureRandomness.cs:53:26:53:58 | return InsecureRandomStringFromSelection | | InsecureRandomness.cs:60:31:60:39 | call to method Next | InsecureRandomness.cs:62:16:62:32 | call to method ToString | -| InsecureRandomness.cs:62:16:62:32 | call to method ToString | InsecureRandomness.cs:53:26:53:58 | return | -| InsecureRandomness.cs:65:26:65:56 | return | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | -| InsecureRandomness.cs:72:31:72:39 | call to method Next | InsecureRandomness.cs:65:26:65:56 | return | +| InsecureRandomness.cs:62:16:62:32 | call to method ToString | InsecureRandomness.cs:53:26:53:58 | return InsecureRandomStringFromSelection | +| InsecureRandomness.cs:65:26:65:56 | return InsecureRandomStringFromIndexer | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | +| InsecureRandomness.cs:72:31:72:39 | call to method Next | InsecureRandomness.cs:65:26:65:56 | return InsecureRandomStringFromIndexer | nodes | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | -| InsecureRandomness.cs:21:26:21:45 | return | +| InsecureRandomness.cs:21:26:21:45 | return InsecureRandomString | | InsecureRandomness.cs:28:29:28:43 | call to method Next | | InsecureRandomness.cs:29:27:29:61 | call to method GetString | | InsecureRandomness.cs:31:16:31:32 | call to method ToString | -| InsecureRandomness.cs:53:26:53:58 | return | +| InsecureRandomness.cs:53:26:53:58 | return InsecureRandomStringFromSelection | | InsecureRandomness.cs:60:31:60:39 | call to method Next | | InsecureRandomness.cs:62:16:62:32 | call to method ToString | -| InsecureRandomness.cs:65:26:65:56 | return | +| InsecureRandomness.cs:65:26:65:56 | return InsecureRandomStringFromIndexer | | InsecureRandomness.cs:72:31:72:39 | call to method Next | #select | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | InsecureRandomness.cs:28:29:28:43 | call to method Next | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | Cryptographically insecure random number is generated at $@ and used here in a security context. | InsecureRandomness.cs:28:29:28:43 | call to method Next | call to method Next | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected b/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected index 3355a8a45909..9fecb9cedd55 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-838/InappropriateEncoding.expected @@ -6,8 +6,8 @@ edges | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | InappropriateEncoding.cs:38:22:38:59 | ... + ... | | InappropriateEncoding.cs:36:28:36:55 | call to method UrlEncode | InappropriateEncoding.cs:39:22:39:71 | call to method Format | | InappropriateEncoding.cs:57:28:57:56 | call to method HtmlEncode | InappropriateEncoding.cs:58:31:58:42 | access to local variable encodedValue | -| InappropriateEncoding.cs:66:19:66:24 | return | InappropriateEncoding.cs:15:28:15:40 | call to method Encode | -| InappropriateEncoding.cs:68:16:68:42 | call to method Replace | InappropriateEncoding.cs:66:19:66:24 | return | +| InappropriateEncoding.cs:66:19:66:24 | return Encode | InappropriateEncoding.cs:15:28:15:40 | call to method Encode | +| InappropriateEncoding.cs:68:16:68:42 | call to method Replace | InappropriateEncoding.cs:66:19:66:24 | return Encode | | SqlEncode.cs:16:62:16:87 | call to method Replace | SqlEncode.cs:17:46:17:50 | access to local variable query | | UrlEncode.cs:12:43:12:69 | call to method HtmlEncode | UrlEncode.cs:12:31:12:69 | ... + ... | nodes @@ -26,7 +26,7 @@ nodes | InappropriateEncoding.cs:39:22:39:71 | call to method Format | | InappropriateEncoding.cs:57:28:57:56 | call to method HtmlEncode | | InappropriateEncoding.cs:58:31:58:42 | access to local variable encodedValue | -| InappropriateEncoding.cs:66:19:66:24 | return | +| InappropriateEncoding.cs:66:19:66:24 | return Encode | | InappropriateEncoding.cs:68:16:68:42 | call to method Replace | | SqlEncode.cs:16:62:16:87 | call to method Replace | | SqlEncode.cs:17:46:17:50 | access to local variable query | From 10491e6497bff5f608ae67a952119ddd1c53ce39 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 11 Mar 2019 10:54:07 +0100 Subject: [PATCH 7/7] C#: More data flow performance tweaks --- .../semmle/code/csharp/dataflow/DataFlow.qll | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index e6a873a16cc4..093cf9365ea3 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -457,6 +457,7 @@ module DataFlow { abstract ArgumentContext getContext(Configuration config); /** Holds if this argument node does not have an associated control flow node. */ + cached abstract predicate hasNoControlFlowNode(); } @@ -864,6 +865,16 @@ module DataFlow { } } + // noopt is needed to force scan of `config.isAdditionalFlowStep` followed + // by join on `getEnclosingCallable()`, instead of the other way around + pragma[noopt] + private predicate isAdditionalFlowStep( + Node pred, Node succ, Configuration config, DotNet::Callable c + ) { + config.isAdditionalFlowStep(pred, succ) and + pred.getEnclosingCallable() = c + } + /** Provides predicates related to local data flow. */ module LocalFlow { private class LocalExprStepConfiguration extends ExprStepConfiguration { @@ -1072,14 +1083,6 @@ module DataFlow { (isSuccessor = true or isSuccessor = false) } - pragma[noinline] - private predicate localFlowStep0( - Node pred, Node succ, Configuration config, DotNet::Callable c - ) { - config.isAdditionalFlowStep(pred, succ) and - pred.getEnclosingCallable() = c - } - /** * Holds if data may flow in one local step from `pred` to `succ`. */ @@ -1087,7 +1090,7 @@ module DataFlow { predicate localFlowStep(Node pred, Node succ, Configuration config) { localFlowStep(pred, succ) or - localFlowStep0(pred, succ, config, succ.getEnclosingCallable()) + isAdditionalFlowStep(pred, succ, config, succ.getEnclosingCallable()) } /** @@ -1163,8 +1166,9 @@ module DataFlow { */ pragma[noinline] private predicate additionalJumpStep(Node node1, Node node2, Configuration config) { - config.isAdditionalFlowStep(node1, node2) and - node1.getEnclosingCallable() != node2.getEnclosingCallable() + exists(DotNet::Callable c1 | isAdditionalFlowStep(node1, node2, config, c1) | + c1 != node2.getEnclosingCallable() + ) } /**