diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index 43555af1af9..b344ea9a864 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node source) { none() } /** - * Holds if `sink` is a relevant taint sink. + * Holds if `source` is a relevant taint source with the given initial + * `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() } + + /** + * Holds if `sink` is a relevant taint sink * * The smaller this predicate is, the faster `hasFlow()` will converge. */ // overridden to provide taint-tracking specific qldoc override predicate isSink(DataFlow::Node sink) { none() } + /** + * Holds if `sink` is a relevant taint sink accepting `state`. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() } + /** Holds if the node `node` is a taint sanitizer. */ predicate isSanitizer(DataFlow::Node node) { none() } @@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration { defaultTaintSanitizer(node) } + /** + * Holds if the node `node` is a taint sanitizer when the flow state is + * `state`. + */ + predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() } + + final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { + this.isSanitizer(node, state) + } + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } @@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration { defaultAdditionalTaintStep(node1, node2) } + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. This step is only applicable + * in `state1` and updates the flow state to `state2`. + */ + predicate isAdditionalTaintStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + final override predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + this.isAdditionalTaintStep(node1, state1, node2, state2) + } + override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) { (this.isSink(node) or this.isAdditionalTaintStep(node, _)) and defaultImplicitTaintRead(node, c)