зеркало из https://github.com/github/codeql.git
JavaScript: Allow summary details to be omitted.
If a summary does not specify a configuration, it is taken to apply to all configurations without custom sanitisers/barriers. If a source summary does not specify a flow label, `data` is assumed. If a sink summary does not specify a flow label, both `data` and `taint` are assumed. Flow step summaries cannot omit flow labels. Note that the standard extraction queries always provide explicit configurations and flow labels, and hence do not exercise this functionality.
This commit is contained in:
Родитель
7c87c43511
Коммит
bdf29d010a
|
@ -6,6 +6,7 @@
|
|||
import javascript
|
||||
import semmle.javascript.dataflow.Portals
|
||||
import external.ExternalArtifact
|
||||
private import Shared
|
||||
|
||||
/**
|
||||
* An additional source specified in an `additional-sources.csv` file.
|
||||
|
@ -26,18 +27,25 @@ class AdditionalSourceSpec extends ExternalData {
|
|||
* Gets the flow label of this source.
|
||||
*/
|
||||
DataFlow::FlowLabel getFlowLabel() {
|
||||
result.toString() = getField(1)
|
||||
sourceFlowLabelSpec(result, getField(1))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configuration for which this is a source.
|
||||
* Gets the configuration for which this is a source, or any
|
||||
* configuration if this source does not specify a configuration.
|
||||
*/
|
||||
DataFlow::Configuration getConfiguration() {
|
||||
result.toString() = getField(2)
|
||||
configSpec(result, getField(2))
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = getPortal() + " as " + getFlowLabel() + " source for " + getConfiguration()
|
||||
exists (string config |
|
||||
if getField(2) = "" then
|
||||
config = "any configuration"
|
||||
else
|
||||
config = getConfiguration() |
|
||||
result = getPortal() + " as " + getFlowLabel() + " source for " + config
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,21 +77,30 @@ class AdditionalSinkSpec extends ExternalData {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the flow label of this sink.
|
||||
* Gets the flow label of this sink, or any standard flow label if this sink
|
||||
* does not specify a flow label.
|
||||
*/
|
||||
DataFlow::FlowLabel getFlowLabel() {
|
||||
result.toString() = getField(1)
|
||||
sinkFlowLabelSpec(result, getField(1))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configuration for which this is a sink.
|
||||
* Gets the configuration for which this is a sink, or any configuration if
|
||||
* this sink does not specify a configuration.
|
||||
*/
|
||||
DataFlow::Configuration getConfiguration() {
|
||||
result.toString() = getField(2)
|
||||
configSpec(result, getField(2))
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = getPortal() + " as " + getFlowLabel() + " sink for " + getConfiguration()
|
||||
exists (string labels, string config |
|
||||
labels = strictconcat(getFlowLabel(), " or ") and
|
||||
if getField(2) = "" then
|
||||
config = "any configuration"
|
||||
else
|
||||
config = getConfiguration() |
|
||||
result = getPortal() + " as " + labels + " sink for " + config
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,13 +155,19 @@ class AdditionalStepSpec extends ExternalData {
|
|||
* Gets the configuration to which this step should be added.
|
||||
*/
|
||||
DataFlow::Configuration getConfiguration() {
|
||||
result.toString() = getField(4)
|
||||
configSpec(result, getField(4))
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "edge from " + getStartPortal() + " to " + getEndPortal() +
|
||||
", transforming " + getStartFlowLabel() + " into " + getEndFlowLabel() +
|
||||
" for " + getConfiguration()
|
||||
exists (string config |
|
||||
if getField(4) = "" then
|
||||
config = "any configuration"
|
||||
else
|
||||
config = getConfiguration() |
|
||||
result = "edge from " + getStartPortal() + " to " + getEndPortal() +
|
||||
", transforming " + getStartFlowLabel() + " into " + getEndFlowLabel() +
|
||||
" for " + config
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import javascript
|
||||
import semmle.javascript.dataflow.Portals
|
||||
import external.ExternalArtifact
|
||||
import Shared
|
||||
|
||||
/**
|
||||
* An external predicate providing information about additional sources.
|
||||
|
@ -42,8 +43,7 @@ private class AdditionalSourceFromSpec extends DataFlow::AdditionalSource {
|
|||
}
|
||||
|
||||
override predicate isSourceFor(DataFlow::Configuration cfg, DataFlow::FlowLabel lbl) {
|
||||
cfg.toString() = config and
|
||||
lbl = flowLabel
|
||||
configSpec(cfg, config) and sourceFlowLabelSpec(lbl, flowLabel)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,8 +61,7 @@ private class AdditionalSinkFromSpec extends DataFlow::AdditionalSink {
|
|||
}
|
||||
|
||||
override predicate isSinkFor(DataFlow::Configuration cfg, DataFlow::FlowLabel lbl) {
|
||||
cfg.toString() = config and
|
||||
lbl = flowLabel
|
||||
configSpec(cfg, config) and sinkFlowLabelSpec(lbl, flowLabel)
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
@ -75,8 +74,9 @@ private class AdditionalFlowStepFromSpec extends DataFlow::Configuration {
|
|||
string endFlowLabel;
|
||||
|
||||
AdditionalFlowStepFromSpec() {
|
||||
exists (Portal startPortal, Portal endPortal |
|
||||
additionalSteps(startPortal.toString(), startFlowLabel, endPortal.toString(), endFlowLabel, this) and
|
||||
exists (Portal startPortal, Portal endPortal, string config |
|
||||
additionalSteps(startPortal.toString(), startFlowLabel, endPortal.toString(), endFlowLabel, config) and
|
||||
configSpec(this, config) and
|
||||
entry = startPortal.getAnEntryNode(_) and
|
||||
exit = endPortal.getAnExitNode(_)
|
||||
)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* Provides utility predicates for working with flow summary specifications.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
/**
|
||||
* Holds if `config` matches `spec`, that is, either `spec` is the name of `config`
|
||||
* or `spec` is the empty string and `config` is an arbitrary configuration.
|
||||
*/
|
||||
predicate configSpec(DataFlow::Configuration config, string spec) {
|
||||
config.toString() = spec
|
||||
or
|
||||
spec = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `lbl` matches `spec`, that is, either `spec` is the name of `config`
|
||||
* or `spec` is the empty string and `lbl` is the built-in flow label `data`.
|
||||
*/
|
||||
predicate sourceFlowLabelSpec(DataFlow::FlowLabel lbl, string spec) {
|
||||
lbl.toString() = spec
|
||||
or
|
||||
spec = "" and
|
||||
lbl = DataFlow::FlowLabel::data()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `lbl` matches `spec`, that is, either `spec` is the name of `config`
|
||||
* or `spec` is the empty string and `lbl` is an arbitrary standard flow label.
|
||||
*/
|
||||
predicate sinkFlowLabelSpec(DataFlow::FlowLabel lbl, string spec) {
|
||||
lbl.toString() = spec
|
||||
or
|
||||
spec = "" and
|
||||
lbl instanceof DataFlow::StandardFlowLabel
|
||||
}
|
Загрузка…
Ссылка в новой задаче