JavaScript: Import flow summaries through external predicates.

This commit is contained in:
Max Schaefer
2018-11-06 11:31:08 +00:00
parent 90ad8e3858
commit 7c87c43511

View File

@@ -0,0 +1,92 @@
/**
* Provides classes for importing source, sink and flow step summaries
* through external predicates.
*/
import javascript
import semmle.javascript.dataflow.Portals
import external.ExternalArtifact
/**
* An external predicate providing information about additional sources.
*
* This predicate can be populated from the output of the `ExtractSourceSummaries` query.
*/
external predicate additionalSources(string portal, string flowLabel, string config);
/**
* An external predicate providing information about additional sinks.
*
* This predicate can be populated from the output of the `ExtractSinkSummaries` query.
*/
external predicate additionalSinks(string portal, string flowLabel, string config);
/**
* An external predicate providing information about additional flow steps.
*
* This predicate can be populated from the output of the `ExtractFlowStepSummaries` query.
*/
external predicate additionalSteps(string startPortal, string startFlowLabel, string endPortal, string endFlowLabel, string config);
/**
* An additional source specified through the `additionalSources` predicate.
*/
private class AdditionalSourceFromSpec extends DataFlow::AdditionalSource {
Portal portal;
string flowLabel;
string config;
AdditionalSourceFromSpec() {
additionalSources(portal.toString(), flowLabel, config) and
this = portal.getAnExitNode(_)
}
override predicate isSourceFor(DataFlow::Configuration cfg, DataFlow::FlowLabel lbl) {
cfg.toString() = config and
lbl = flowLabel
}
}
/**
* An additional sink specified through the `additionalSinks` predicate.
*/
private class AdditionalSinkFromSpec extends DataFlow::AdditionalSink {
Portal portal;
string flowLabel;
string config;
AdditionalSinkFromSpec() {
additionalSinks(portal.toString(), flowLabel, config) and
this = portal.getAnEntryNode(_)
}
override predicate isSinkFor(DataFlow::Configuration cfg, DataFlow::FlowLabel lbl) {
cfg.toString() = config and
lbl = flowLabel
}
}
/**
* An additional flow step specified through the `additionalSteps` predicate.
*/
private class AdditionalFlowStepFromSpec extends DataFlow::Configuration {
DataFlow::Node entry;
string startFlowLabel;
DataFlow::Node exit;
string endFlowLabel;
AdditionalFlowStepFromSpec() {
exists (Portal startPortal, Portal endPortal |
additionalSteps(startPortal.toString(), startFlowLabel, endPortal.toString(), endFlowLabel, this) and
entry = startPortal.getAnEntryNode(_) and
exit = endPortal.getAnExitNode(_)
)
}
override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ,
DataFlow::FlowLabel predlbl, DataFlow::FlowLabel succlbl) {
pred = entry and
succ = exit and
predlbl = startFlowLabel and
succlbl = endFlowLabel
}
}