C#: Add alert provenance plumbing.

This commit is contained in:
Anders Schack-Mulligen
2024-02-02 15:37:15 +01:00
parent eafc0075fd
commit 004bda1ee0
13 changed files with 164 additions and 110 deletions

View File

@@ -5,6 +5,7 @@ private import DataFlowImplCommon
private import ControlFlowReachability
private import FlowSummaryImpl as FlowSummaryImpl
private import semmle.code.csharp.dataflow.FlowSummary as FlowSummary
private import semmle.code.csharp.dataflow.internal.ExternalFlow
private import semmle.code.csharp.Conversion
private import semmle.code.csharp.dataflow.internal.SsaImpl as SsaImpl
private import semmle.code.csharp.ExprOrStmtParent
@@ -796,7 +797,7 @@ module LocalFlow {
node1 =
unique(FlowSummaryNode n1 |
FlowSummaryImpl::Private::Steps::summaryLocalStep(n1.getSummaryNode(),
node2.(FlowSummaryNode).getSummaryNode(), true)
node2.(FlowSummaryNode).getSummaryNode(), true, _)
)
}
}
@@ -809,36 +810,39 @@ predicate localMustFlowStep = LocalFlow::localMustFlowStep/2;
* is handled by the global data-flow library, but includes various other steps
* that are only relevant for global flow.
*/
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
or
exists(SsaImpl::DefinitionExt def |
not LocalFlow::usesInstanceField(def) and
not def instanceof VariableCapture::CapturedSsaDefinitionExt
|
LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo)
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
(
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
or
LocalFlow::localSsaFlowStepUseUse(def, nodeFrom, nodeTo) and
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _) and
nodeFrom != nodeTo
or
// Flow into phi (read)/uncertain SSA definition node from read
exists(Node read | LocalFlow::localFlowSsaInputFromRead(read, def, nodeTo) |
nodeFrom = read and
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _)
exists(SsaImpl::DefinitionExt def |
not LocalFlow::usesInstanceField(def) and
not def instanceof VariableCapture::CapturedSsaDefinitionExt
|
LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo)
or
nodeFrom.(PostUpdateNode).getPreUpdateNode() = read
LocalFlow::localSsaFlowStepUseUse(def, nodeFrom, nodeTo) and
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _) and
nodeFrom != nodeTo
or
// Flow into phi (read)/uncertain SSA definition node from read
exists(Node read | LocalFlow::localFlowSsaInputFromRead(read, def, nodeTo) |
nodeFrom = read and
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _)
or
nodeFrom.(PostUpdateNode).getPreUpdateNode() = read
)
)
)
or
nodeTo.(ObjectCreationNode).getPreUpdateNode() = nodeFrom.(ObjectInitializerNode)
or
VariableCapture::valueStep(nodeFrom, nodeTo)
or
nodeTo = nodeFrom.(LocalFunctionCreationNode).getAnAccess(true)
) and
model = ""
or
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
nodeTo.(FlowSummaryNode).getSummaryNode(), true)
or
nodeTo.(ObjectCreationNode).getPreUpdateNode() = nodeFrom.(ObjectInitializerNode)
or
VariableCapture::valueStep(nodeFrom, nodeTo)
or
nodeTo = nodeFrom.(LocalFunctionCreationNode).getAnAccess(true)
nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
}
/**
@@ -902,7 +906,7 @@ private predicate fieldOrPropertyStore(Expr e, Content c, Expr src, Expr q, bool
FlowSummaryImpl::Private::SummarizedCallableImpl sc,
FlowSummaryImpl::Private::SummaryComponentStack input
|
sc.propagatesFlow(input, _, _) and
sc.propagatesFlow(input, _, _, _) and
input.contains(FlowSummaryImpl::Private::SummaryComponent::content(f.getContent()))
)
)
@@ -2874,6 +2878,10 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
preservesValue = true
}
predicate knownSourceModel(Node source, string model) { sourceNode(source, _, model) }
predicate knownSinkModel(Node sink, string model) { sinkNode(sink, _, model) }
/**
* Holds if flow is allowed to pass from parameter `p` and back to itself as a
* side-effect, resulting in a summary from `p` to itself.

View File

@@ -97,9 +97,9 @@ private import semmle.code.csharp.commons.QualifiedName
private import codeql.mad.ModelValidation as SharedModelVal
private predicate relevantNamespace(string namespace) {
sourceModel(namespace, _, _, _, _, _, _, _, _) or
sinkModel(namespace, _, _, _, _, _, _, _, _) or
summaryModel(namespace, _, _, _, _, _, _, _, _, _)
sourceModel(namespace, _, _, _, _, _, _, _, _, _) or
sinkModel(namespace, _, _, _, _, _, _, _, _, _) or
summaryModel(namespace, _, _, _, _, _, _, _, _, _, _)
}
private predicate namespaceLink(string shortns, string longns) {
@@ -129,7 +129,7 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
strictcount(string subns, string type, boolean subtypes, string name, string signature,
string ext, string output, string provenance |
canonicalNamespaceLink(namespace, subns) and
sourceModel(subns, type, subtypes, name, signature, ext, output, kind, provenance)
sourceModel(subns, type, subtypes, name, signature, ext, output, kind, provenance, _)
)
or
part = "sink" and
@@ -137,7 +137,7 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
strictcount(string subns, string type, boolean subtypes, string name, string signature,
string ext, string input, string provenance |
canonicalNamespaceLink(namespace, subns) and
sinkModel(subns, type, subtypes, name, signature, ext, input, kind, provenance)
sinkModel(subns, type, subtypes, name, signature, ext, input, kind, provenance, _)
)
or
part = "summary" and
@@ -145,7 +145,7 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
strictcount(string subns, string type, boolean subtypes, string name, string signature,
string ext, string input, string output, string provenance |
canonicalNamespaceLink(namespace, subns) and
summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, provenance)
summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, provenance, _)
)
)
}
@@ -155,10 +155,10 @@ module ModelValidation {
private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax
private predicate getRelevantAccessPath(string path) {
summaryModel(_, _, _, _, _, _, path, _, _, _) or
summaryModel(_, _, _, _, _, _, _, path, _, _) or
sinkModel(_, _, _, _, _, _, path, _, _) or
sourceModel(_, _, _, _, _, _, path, _, _)
summaryModel(_, _, _, _, _, _, path, _, _, _, _) or
summaryModel(_, _, _, _, _, _, _, path, _, _, _) or
sinkModel(_, _, _, _, _, _, path, _, _, _) or
sourceModel(_, _, _, _, _, _, path, _, _, _)
}
private module MkAccessPath = AccessPathSyntax::AccessPath<getRelevantAccessPath/1>;
@@ -169,9 +169,9 @@ module ModelValidation {
private string getInvalidModelInput() {
exists(string pred, AccessPath input, AccessPathToken part |
sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink"
sinkModel(_, _, _, _, _, _, input, _, _, _) and pred = "sink"
or
summaryModel(_, _, _, _, _, _, input, _, _, _) and pred = "summary"
summaryModel(_, _, _, _, _, _, input, _, _, _, _) and pred = "summary"
|
(
invalidSpecComponent(input, part) and
@@ -191,9 +191,9 @@ module ModelValidation {
private string getInvalidModelOutput() {
exists(string pred, AccessPath output, AccessPathToken part |
sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source"
sourceModel(_, _, _, _, _, _, output, _, _, _) and pred = "source"
or
summaryModel(_, _, _, _, _, _, _, output, _, _) and pred = "summary"
summaryModel(_, _, _, _, _, _, _, output, _, _, _) and pred = "summary"
|
(
invalidSpecComponent(output, part) and
@@ -208,11 +208,11 @@ module ModelValidation {
}
private module KindValConfig implements SharedModelVal::KindValidationConfigSig {
predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) }
predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _, _) }
predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) }
predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _, _) }
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) }
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _, _) }
predicate neutralKind(string kind) { neutralModel(_, _, _, _, kind, _) }
}
@@ -224,11 +224,11 @@ module ModelValidation {
string pred, string namespace, string type, string name, string signature, string ext,
string provenance
|
sourceModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "source"
sourceModel(namespace, type, _, name, signature, ext, _, _, provenance, _) and pred = "source"
or
sinkModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "sink"
sinkModel(namespace, type, _, name, signature, ext, _, _, provenance, _) and pred = "sink"
or
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance, _) and
pred = "summary"
or
neutralModel(namespace, type, name, signature, _, provenance) and
@@ -268,11 +268,11 @@ module ModelValidation {
private predicate elementSpec(
string namespace, string type, boolean subtypes, string name, string signature, string ext
) {
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _)
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _, _)
or
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _)
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _, _)
or
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _)
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _)
or
neutralModel(namespace, type, name, signature, _, _) and ext = "" and subtypes = false
}
@@ -393,14 +393,14 @@ Declaration interpretElement(
* A callable where there exists a MaD sink model that applies to it.
*/
class SinkCallable extends Callable {
SinkCallable() { SourceSinkInterpretationInput::sinkElement(this, _, _, _) }
SinkCallable() { SourceSinkInterpretationInput::sinkElement(this, _, _, _, _) }
}
/**
* A callable where there exists a MaD source model that applies to it.
*/
class SourceCallable extends Callable {
SourceCallable() { SourceSinkInterpretationInput::sourceElement(this, _, _, _) }
SourceCallable() { SourceSinkInterpretationInput::sourceElement(this, _, _, _, _) }
}
cached
@@ -410,9 +410,9 @@ private module Cached {
* model.
*/
cached
predicate sourceNode(Node node, string kind) {
predicate sourceNode(Node node, string kind, string model) {
exists(SourceSinkInterpretationInput::InterpretNode n |
isSourceNode(n, kind) and n.asNode() = node
isSourceNode(n, kind, model) and n.asNode() = node
)
}
@@ -421,15 +421,27 @@ private module Cached {
* model.
*/
cached
predicate sinkNode(Node node, string kind) {
predicate sinkNode(Node node, string kind, string model) {
exists(SourceSinkInterpretationInput::InterpretNode n |
isSinkNode(n, kind) and n.asNode() = node
isSinkNode(n, kind, model) and n.asNode() = node
)
}
}
import Cached
/**
* Holds if `node` is specified as a source with the given kind in a MaD flow
* model.
*/
predicate sourceNode(Node node, string kind) { sourceNode(node, kind, _) }
/**
* Holds if `node` is specified as a sink with the given kind in a MaD flow
* model.
*/
predicate sinkNode(Node node, string kind) { sinkNode(node, kind, _) }
/** Holds if the summary should apply for all overrides of `c`. */
predicate isBaseCallableOrPrototype(UnboundCallable c) {
c.getDeclaringType() instanceof Interface
@@ -517,12 +529,15 @@ string asPartialNeutralModel(UnboundCallable c) {
}
private predicate interpretSummary(
UnboundCallable c, string input, string output, string kind, string provenance
UnboundCallable c, string input, string output, string kind, string provenance, string model
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
string namespace, string type, boolean subtypes, string name, string signature, string ext,
QlBuiltins::ExtensionId madId
|
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) and
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance,
madId) and
model = "MaD:" + madId.toString() and
c = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
@@ -536,18 +551,22 @@ private predicate interpretNeutral(UnboundCallable c, string kind, string proven
// adapter class for converting Mad summaries to `SummarizedCallable`s
private class SummarizedCallableAdapter extends SummarizedCallable {
SummarizedCallableAdapter() { interpretSummary(this, _, _, _, _) }
SummarizedCallableAdapter() { interpretSummary(this, _, _, _, _, _) }
private predicate relevantSummaryElementManual(string input, string output, string kind) {
private predicate relevantSummaryElementManual(
string input, string output, string kind, string model
) {
exists(Provenance provenance |
interpretSummary(this, input, output, kind, provenance) and
interpretSummary(this, input, output, kind, provenance, model) and
provenance.isManual()
)
}
private predicate relevantSummaryElementGenerated(string input, string output, string kind) {
private predicate relevantSummaryElementGenerated(
string input, string output, string kind, string model
) {
exists(Provenance provenance |
interpretSummary(this, input, output, kind, provenance) and
interpretSummary(this, input, output, kind, provenance, model) and
provenance.isGenerated()
) and
not exists(Provenance provenance |
@@ -556,19 +575,21 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
)
}
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
override predicate propagatesFlow(
string input, string output, boolean preservesValue, string model
) {
exists(string kind |
this.relevantSummaryElementManual(input, output, kind)
this.relevantSummaryElementManual(input, output, kind, model)
or
not this.relevantSummaryElementManual(_, _, _) and
this.relevantSummaryElementGenerated(input, output, kind)
not this.relevantSummaryElementManual(_, _, _, _) and
this.relevantSummaryElementGenerated(input, output, kind, model)
|
if kind = "value" then preservesValue = true else preservesValue = false
)
}
override predicate hasProvenance(Provenance provenance) {
interpretSummary(this, _, _, _, provenance)
interpretSummary(this, _, _, _, provenance, _)
}
}

View File

@@ -7,7 +7,7 @@
*/
extensible predicate sourceModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
);
/**
@@ -15,7 +15,7 @@ extensible predicate sourceModel(
*/
extensible predicate sinkModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string kind, string provenance
string input, string kind, string provenance, QlBuiltins::ExtensionId madId
);
/**
@@ -23,7 +23,7 @@ extensible predicate sinkModel(
*/
extensible predicate summaryModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string output, string kind, string provenance
string input, string output, string kind, string provenance, QlBuiltins::ExtensionId madId
);
/**

View File

@@ -169,20 +169,28 @@ module SourceSinkInterpretationInput implements
class Element = Cs::Element;
predicate sourceElement(Element e, string output, string kind, Public::Provenance provenance) {
predicate sourceElement(
Element e, string output, string kind, Public::Provenance provenance, string model
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
string namespace, string type, boolean subtypes, string name, string signature, string ext,
QlBuiltins::ExtensionId madId
|
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance) and
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, madId) and
model = "MaD:" + madId.toString() and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
predicate sinkElement(Element e, string input, string kind, Public::Provenance provenance) {
predicate sinkElement(
Element e, string input, string kind, Public::Provenance provenance, string model
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
string namespace, string type, boolean subtypes, string name, string signature, string ext,
QlBuiltins::ExtensionId madId
|
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance) and
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance, madId) and
model = "MaD:" + madId.toString() and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
@@ -380,10 +388,13 @@ private class SummarizedCallableWithCallback extends Public::SummarizedCallable
SummarizedCallableWithCallback() { mayInvokeCallback(this, pos) }
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
override predicate propagatesFlow(
string input, string output, boolean preservesValue, string model
) {
input = "Argument[" + pos + "]" and
output = "Argument[" + pos + "].Parameter[delegate-self]" and
preservesValue = true
preservesValue = true and
model = "heuristic-callback"
}
override predicate hasProvenance(Public::Provenance provenance) { provenance = "hq-generated" }

View File

@@ -150,21 +150,24 @@ private module Cached {
* in all global taint flow configurations.
*/
cached
predicate defaultAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
localTaintStepCommon(nodeFrom, nodeTo)
or
// Taint members
readStep(nodeFrom, any(TaintedMember m).(FieldOrProperty).getContent(), nodeTo)
or
// Although flow through collections is modeled precisely using stores/reads, we still
// allow flow out of a _tainted_ collection. This is needed in order to support taint-
// tracking configurations where the source is a collection
readStep(nodeFrom, TElementContent(), nodeTo)
predicate defaultAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, string model) {
(
localTaintStepCommon(nodeFrom, nodeTo)
or
// Taint members
readStep(nodeFrom, any(TaintedMember m).(FieldOrProperty).getContent(), nodeTo)
or
// Although flow through collections is modeled precisely using stores/reads, we still
// allow flow out of a _tainted_ collection. This is needed in order to support taint-
// tracking configurations where the source is a collection
readStep(nodeFrom, TElementContent(), nodeTo)
or
nodeTo = nodeFrom.(DataFlow::NonLocalJumpNode).getAJumpSuccessor(false)
) and
model = ""
or
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
nodeTo.(FlowSummaryNode).getSummaryNode(), false)
or
nodeTo = nodeFrom.(DataFlow::NonLocalJumpNode).getAJumpSuccessor(false)
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
}
}

View File

@@ -99,7 +99,9 @@ module EntityFramework {
// see `SummarizedCallableImpl` qldoc
private class EFSummarizedCallableAdapter extends SummarizedCallable instanceof EFSummarizedCallable
{
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
override predicate propagatesFlow(
string input, string output, boolean preservesValue, string model
) {
none()
}
@@ -174,11 +176,13 @@ module EntityFramework {
}
override predicate propagatesFlow(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue,
string model
) {
input = SummaryComponentStack::argument(0) and
output = SummaryComponentStack::return() and
preservesValue = false
preservesValue = false and
model = "RawSqlStringConstructorSummarizedCallable"
}
}
@@ -188,11 +192,13 @@ module EntityFramework {
}
override predicate propagatesFlow(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue,
string model
) {
input = SummaryComponentStack::argument(0) and
output = SummaryComponentStack::return() and
preservesValue = false
preservesValue = false and
model = "RawSqlStringConversionSummarizedCallable"
}
}
@@ -463,12 +469,14 @@ module EntityFramework {
DbContextClassSetPropertySynthetic() { this = p.getGetter() }
override predicate propagatesFlow(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue,
string model
) {
exists(string name, DbContextClass c |
preservesValue = true and
name = c.getSyntheticName(output, _, p) and
input = SummaryComponentStack::syntheticGlobal(name)
input = SummaryComponentStack::syntheticGlobal(name) and
model = "DbContextClassSetPropertySynthetic"
)
}
}
@@ -479,13 +487,15 @@ module EntityFramework {
DbContextSaveChanges() { this = c.getASaveChanges() }
override predicate propagatesFlow(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue,
string model
) {
exists(string name, Property mapped |
preservesValue = true and
c.input(input, mapped) and
name = c.getSyntheticName(_, mapped, _) and
output = SummaryComponentStack::syntheticGlobal(name)
output = SummaryComponentStack::syntheticGlobal(name) and
model = "DbContextSaveChanges"
)
}
}

View File

@@ -74,7 +74,7 @@ class ExternalApi extends Callable {
predicate hasSummary() {
this instanceof SummarizedCallable
or
defaultAdditionalTaintStep(this.getAnInput(), _)
defaultAdditionalTaintStep(this.getAnInput(), _, _)
}
/** Holds if this API is a known source. */

View File

@@ -12,7 +12,7 @@ from
string name, string signature0, string signature, string ext, string input, string kind,
string provenance
where
sinkModel(namespace0, type0, subtypes, name0, signature0, ext, input, kind, provenance) and
sinkModel(namespace0, type0, subtypes, name0, signature0, ext, input, kind, provenance, _) and
interpretCallable(namespace0, namespace, type0, type, name0, name, signature0, signature)
select namespace, type, subtypes, name, signature, ext, input, kind, provenance order by
namespace, type, name, signature, input, kind

View File

@@ -12,7 +12,7 @@ from
string name, string signature0, string signature, string ext, string output, string kind,
string provenance
where
sourceModel(namespace0, type0, subtypes, name0, signature0, ext, output, kind, provenance) and
sourceModel(namespace0, type0, subtypes, name0, signature0, ext, output, kind, provenance, _) and
interpretCallable(namespace0, namespace, type0, type, name0, name, signature0, signature)
select namespace, type, subtypes, name, signature, ext, output, kind, provenance order by
namespace, type, name, signature, output, kind

View File

@@ -12,7 +12,8 @@ from
string name, string signature0, string signature, string ext, string input, string output,
string kind, string provenance
where
summaryModel(namespace0, type0, subtypes, name0, signature0, ext, input, output, kind, provenance) and
summaryModel(namespace0, type0, subtypes, name0, signature0, ext, input, output, kind, provenance,
_) and
interpretCallable(namespace0, namespace, type0, type, name0, name, signature0, signature)
select namespace, type, subtypes, name, signature, ext, input, output, kind, provenance order by
namespace, type, name, signature, input, output, kind

View File

@@ -34,7 +34,7 @@ class ExternalEndpoint extends Endpoint {
override predicate hasSummary() {
Endpoint.super.hasSummary()
or
defaultAdditionalTaintStep(this.getAnInput(), _)
defaultAdditionalTaintStep(this.getAnInput(), _, _)
}
override predicate isSource() {

View File

@@ -10,10 +10,10 @@ class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable {
override predicate relevantSummary(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
) {
this.propagatesFlow(input, output, preservesValue) and
this.propagatesFlow(input, output, preservesValue, _) and
not exists(IncludeSummarizedCallable rsc |
isBaseCallableOrPrototype(rsc) and
rsc.propagatesFlow(input, output, preservesValue) and
rsc.propagatesFlow(input, output, preservesValue, _) and
this.(UnboundCallable).overridesOrImplementsUnbound(rsc)
)
}

View File

@@ -15,6 +15,6 @@ class IncludeSummarizedCallable extends SummarizedCallableImplFinal {
predicate relevantSummary(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
) {
this.propagatesFlow(input, output, preservesValue)
this.propagatesFlow(input, output, preservesValue, _)
}
}