Skip to content

Commit 65abf48

Browse files
committed
PS: Add missing taint-flow and dataflow dispatch from models.
1 parent f482c9d commit 65abf48

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowDispatch.qll

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,12 @@ class AdditionalCallTarget extends Unit {
242242
abstract DataFlowCallable viableTarget(CfgNodes::ExprNodes::CallExprCfgNode call);
243243
}
244244

245+
DataFlowCallable viableSourceCallable(DataFlowCall call) {
246+
result.asCfgScope() = getTargetInstance(call.asCall())
247+
or
248+
result = any(AdditionalCallTarget t).viableTarget(call.asCall())
249+
}
250+
245251
/** Holds if `call` may resolve to the returned summarized library method. */
246252
DataFlowCallable viableLibraryCallable(DataFlowCall call) {
247253
exists(LibraryCallable callable |
@@ -269,13 +275,13 @@ private module Cached {
269275
/** Gets a viable run-time target for the call `call`. */
270276
cached
271277
DataFlowCallable viableCallable(DataFlowCall call) {
272-
result.asCfgScope() = getTargetInstance(call.asCall())
278+
result = viableSourceCallable(call)
273279
or
274-
result = any(AdditionalCallTarget t).viableTarget(call.asCall())
280+
result = viableLibraryCallable(call)
275281
}
276282

277283
cached
278-
CfgScope getTarget(DataFlowCall call) { result = viableCallable(call).asCfgScope() }
284+
CfgScope getTarget(DataFlowCall call) { result = viableSourceCallable(call).asCfgScope() }
279285

280286
cached
281287
newtype TArgumentPosition =

powershell/ql/lib/semmle/code/powershell/dataflow/internal/TaintTrackingPrivate.qll

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ private import DataFlowPrivate
33
private import TaintTrackingPublic
44
private import semmle.code.powershell.Cfg
55
private import semmle.code.powershell.dataflow.DataFlow
6+
private import FlowSummaryImpl as FlowSummaryImpl
67

78
/**
89
* Holds if `node` should be a sanitizer in all global taint flow configurations
@@ -58,6 +59,16 @@ private module Cached {
5859
)
5960
) and
6061
model = ""
62+
or
63+
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
64+
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
65+
}
66+
67+
cached
68+
predicate summaryThroughStepTaint(
69+
DataFlow::Node arg, DataFlow::Node out, FlowSummaryImpl::Public::SummarizedCallable sc
70+
) {
71+
FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(arg, out, sc)
6172
}
6273

6374
/**
@@ -67,7 +78,10 @@ private module Cached {
6778
cached
6879
predicate localTaintStepCached(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
6980
DataFlow::localFlowStep(nodeFrom, nodeTo) or
70-
defaultAdditionalTaintStep(nodeFrom, nodeTo, _)
81+
defaultAdditionalTaintStep(nodeFrom, nodeTo, _) or
82+
// Simple flow through library code is included in the exposed local
83+
// step relation, even though flow is technically inter-procedural
84+
summaryThroughStepTaint(nodeFrom, nodeTo, _)
7185
}
7286
}
7387

0 commit comments

Comments
 (0)