From 7c87c435113b98e45270aa86f811caef36ebaa19 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Tue, 6 Nov 2018 11:31:08 +0000 Subject: [PATCH] JavaScript: Import flow summaries through external predicates. --- .../ImportFromExternalPredicates.qll | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 javascript/ql/src/Security/Summaries/ImportFromExternalPredicates.qll diff --git a/javascript/ql/src/Security/Summaries/ImportFromExternalPredicates.qll b/javascript/ql/src/Security/Summaries/ImportFromExternalPredicates.qll new file mode 100644 index 00000000000..cc6a4d50f2d --- /dev/null +++ b/javascript/ql/src/Security/Summaries/ImportFromExternalPredicates.qll @@ -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 + } +}