diff --git a/config/identical-files.json b/config/identical-files.json index c4436872b9ae..579a22379e84 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -1,58 +1,4 @@ { - "DataFlow Java/C++/C#/Go/Python/Ruby/Swift Legacy Configuration": [ - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll", - "go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll", - "go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll", - "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll", - "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll", - "swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll" - ], - "TaintTracking Legacy Configuration Java/C++/C#/Go/Python/Ruby/Swift": [ - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll", - "go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", - "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll", - "ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", - "swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll" - ], "SsaReadPosition Java/C#": [ "java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll" diff --git a/cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 000000000000..d09ec528c99e --- /dev/null +++ b/cpp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow.qll index 505b2e190e54..a478da5193e0 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow.qll @@ -29,5 +29,5 @@ deprecated module DataFlow { private import semmle.code.cpp.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.code.cpp.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow2.qll deleted file mode 100644 index 19ffa16b76c6..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow2.qll +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Provides a `DataFlow2` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -/** - * DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow2` instead. - * - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -deprecated module DataFlow2 { - import semmle.code.cpp.dataflow.internal.DataFlowImpl2 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow3.qll deleted file mode 100644 index 554b2e155b4c..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow3.qll +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Provides a `DataFlow3` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -/** - * DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow3` instead. - * - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -deprecated module DataFlow3 { - import semmle.code.cpp.dataflow.internal.DataFlowImpl3 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow4.qll deleted file mode 100644 index fdd4e8ab7aef..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/DataFlow4.qll +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Provides a `DataFlow4` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -/** - * DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow4` instead. - * - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -deprecated module DataFlow4 { - import semmle.code.cpp.dataflow.internal.DataFlowImpl4 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/RecursionPrevention.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/RecursionPrevention.qll deleted file mode 100644 index 2d8b52f86225..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/RecursionPrevention.qll +++ /dev/null @@ -1,39 +0,0 @@ -/** - * DEPRECATED: Recursion through `DataFlow::Configuration` is impossible in - * any supported tooling. There is no need for this module because it's - * impossible to accidentally depend on recursion through - * `DataFlow::Configuration` in current releases. - * - * When this module is imported, recursive use of `DataFlow::Configuration` is - * disallowed. Importing this module will guarantee the absence of such - * recursion, which is unsupported and will be unconditionally disallowed in a - * future release. - * - * Recursive use of `DataFlow{2..4}::Configuration` is always disallowed, so no - * import is needed for those. - */ - -import cpp -private import semmle.code.cpp.dataflow.DataFlow - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - * Four copies are available: `DataFlow` through `DataFlow4`. - */ -abstract private class ConfigurationRecursionPrevention extends DataFlow::Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - strictcount(DataFlow::Node n | this.isSource(n)) < 0 - or - strictcount(DataFlow::Node n | this.isSink(n)) < 0 - or - strictcount(DataFlow::Node n1, DataFlow::Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll index 1f93e2a74dff..36af8d9660bb 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll @@ -16,7 +16,6 @@ */ import semmle.code.cpp.dataflow.DataFlow -import semmle.code.cpp.dataflow.DataFlow2 /** * DEPRECATED: Use `semmle.code.cpp.dataflow.new.TaintTracking` instead. @@ -25,10 +24,9 @@ import semmle.code.cpp.dataflow.DataFlow2 * global (inter-procedural) taint-tracking analyses. */ deprecated module TaintTracking { - import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.code.cpp.dataflow.internal.TaintTrackingUtil private import semmle.code.cpp.dataflow.internal.DataFlowImplSpecific private import semmle.code.cpp.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking import TaintFlowMake - import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking2.qll deleted file mode 100644 index dce00316cbbf..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking2.qll +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Provides a `TaintTracking2` module, which is a copy of the `TaintTracking` - * module. Use this class when data-flow configurations or taint-tracking - * configurations must depend on each other. Two classes extending - * `DataFlow::Configuration` should never depend on each other, but one of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The - * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and - * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. - * - * See `semmle.code.cpp.dataflow.TaintTracking` for the full documentation. - */ - -/** - * DEPRECATED: Use `semmle.code.cpp.dataflow.new.TaintTracking2` instead. - * - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -deprecated module TaintTracking2 { - import semmle.code.cpp.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index b4f325e01dfb..4a8ea4ebd43d 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -729,41 +729,39 @@ private predicate exprToDefinitionByReferenceStep(Expr exprIn, Expr argOut) { private module FieldFlow { private import DataFlowImplCommon - private import DataFlowImplLocal private import DataFlowPrivate + private import semmle.code.cpp.dataflow.DataFlow /** - * A configuration for finding local-only flow through fields. This uses the - * `Configuration` class in the dedicated `DataFlowImplLocal` copy of the - * shared library that's not user-exposed directly. + * A configuration for finding local-only flow through fields. * * To keep the flow local to a single function, we put barriers on parameters * and return statements. Sources and sinks are the values that go into and * out of fields, respectively. */ - private class FieldConfiguration extends Configuration { - FieldConfiguration() { this = "FieldConfiguration" } - - override predicate isSource(Node source) { + private module FieldConfig implements DataFlow::ConfigSig { + predicate isSource(Node source) { storeStep(source, _, _) or // Also mark `foo(a.b);` as a source when `a.b` may be overwritten by `foo`. readStep(_, _, any(Node node | node.asExpr() = source.asDefiningArgument())) } - override predicate isSink(Node sink) { readStep(_, _, sink) } + predicate isSink(Node sink) { readStep(_, _, sink) } - override predicate isBarrier(Node node) { node instanceof ParameterNode } + predicate isBarrier(Node node) { node instanceof ParameterNode } - override predicate isBarrierOut(Node node) { + predicate isBarrierOut(Node node) { node.asExpr().getParent() instanceof ReturnStmt or node.asExpr().getParent() instanceof ThrowExpr } } + private module Flow = DataFlow::Global; + predicate fieldFlow(Node node1, Node node2) { - exists(FieldConfiguration cfg | cfg.hasFlow(node1, node2)) and + Flow::flow(node1, node2) and // This configuration should not be able to cross function boundaries, but // we double-check here just to be sure. getNodeEnclosingCallable(node1) = getNodeEnclosingCallable(node2) 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index f9346e284349..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - */ - -import semmle.code.cpp.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.cpp.dataflow.DataFlow::DataFlow as DataFlow - import semmle.code.cpp.dataflow.internal.DataFlowImpl as DataFlowInternal -} 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index e935b8d4d08f..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,9 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - */ - -import semmle.code.cpp.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.cpp.dataflow.DataFlow2::DataFlow2 as DataFlow -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow.qll index bcbebd0de1ed..2067dc8aac00 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow.qll @@ -29,5 +29,5 @@ module DataFlow { private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow2.qll deleted file mode 100644 index 35c5a34a6564..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow2.qll +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Provides a `DataFlow2` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.new.DataFlow` for the full documentation. - */ - -import cpp - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow2 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl2 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow3.qll deleted file mode 100644 index e2e402835f25..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow3.qll +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Provides a `DataFlow3` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.new.DataFlow` for the full documentation. - */ - -import cpp - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow3 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl3 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow4.qll deleted file mode 100644 index f9209abe1e15..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/DataFlow4.qll +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Provides a `DataFlow4` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.dataflow.new.DataFlow` for the full documentation. - */ - -import cpp - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow4 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl4 -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking.qll index d28a389203fa..ecc927ecad7c 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking.qll @@ -16,18 +16,16 @@ */ import semmle.code.cpp.dataflow.new.DataFlow -import semmle.code.cpp.dataflow.new.DataFlow2 /** * Provides classes for performing local (intra-procedural) and * global (inter-procedural) taint-tracking analyses. */ module TaintTracking { - import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific private import semmle.code.cpp.ir.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking private import semmle.code.cpp.Location import TaintFlowMake - import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking2.qll deleted file mode 100644 index 2da049cefafa..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking2.qll +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Provides a `TaintTracking2` module, which is a copy of the `TaintTracking` - * module. Use this class when data-flow configurations or taint-tracking - * configurations must depend on each other. Two classes extending - * `DataFlow::Configuration` should never depend on each other, but one of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The - * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and - * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. - * - * See `semmle.code.cpp.dataflow.new.TaintTracking` for the full documentation. - */ - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking2 { - import semmle.code.cpp.ir.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking3.qll deleted file mode 100644 index 113175d83698..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/new/TaintTracking3.qll +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Provides a `TaintTracking3` module, which is a copy of the `TaintTracking` - * module. Use this class when data-flow configurations or taint-tracking - * configurations must depend on each other. Two classes extending - * `DataFlow::Configuration` should never depend on each other, but one of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The - * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and - * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. - * - * See `semmle.code.cpp.dataflow.new.TaintTracking` for the full documentation. - */ - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking3 { - import semmle.code.cpp.ir.dataflow.internal.tainttracking3.TaintTrackingImpl -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow.qll index 671d82c74efd..ecd474d64b28 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow.qll @@ -25,5 +25,5 @@ module DataFlow { private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow2.qll deleted file mode 100644 index 95eb979192d3..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow2.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Provides a `DataFlow2` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.ir.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -module DataFlow2 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl2 -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow3.qll deleted file mode 100644 index 42529f78e5be..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow3.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Provides a `DataFlow3` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.ir.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -module DataFlow3 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl3 -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow4.qll deleted file mode 100644 index 6cd49e39e710..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DataFlow4.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Provides a `DataFlow4` module, which is a copy of the `DataFlow` module. Use - * this class when data-flow configurations must depend on each other. Two - * classes extending `DataFlow::Configuration` should never depend on each - * other, but one of them should instead depend on a - * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a - * `DataFlow4::Configuration`. - * - * See `semmle.code.cpp.ir.dataflow.DataFlow` for the full documentation. - */ - -import cpp - -module DataFlow4 { - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl4 -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll index 9ca1315ec3e5..69bb1978cf60 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll @@ -16,13 +16,11 @@ */ import semmle.code.cpp.ir.dataflow.DataFlow -import semmle.code.cpp.ir.dataflow.DataFlow2 module TaintTracking { - import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific private import semmle.code.cpp.ir.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking import TaintFlowMake - import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking2.qll deleted file mode 100644 index 3ef03a3bd2cb..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking2.qll +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Provides a `TaintTracking2` module, which is a copy of the `TaintTracking` - * module. Use this class when data-flow configurations or taint-tracking - * configurations must depend on each other. Two classes extending - * `DataFlow::Configuration` should never depend on each other, but one of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The - * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and - * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. - * - * See `semmle.code.cpp.ir.dataflow.TaintTracking` for the full documentation. - */ -module TaintTracking2 { - import semmle.code.cpp.ir.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking3.qll deleted file mode 100644 index 98e1caebf388..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking3.qll +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Provides a `TaintTracking3` module, which is a copy of the `TaintTracking` - * module. Use this class when data-flow configurations or taint-tracking - * configurations must depend on each other. Two classes extending - * `DataFlow::Configuration` should never depend on each other, but one of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The - * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and - * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. - * - * See `semmle.code.cpp.ir.dataflow.TaintTracking` for the full documentation. - */ -module TaintTracking3 { - import semmle.code.cpp.ir.dataflow.internal.tainttracking3.TaintTrackingImpl -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index 19e10871a781..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow as DataFlow - import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl as DataFlowInternal -} 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingParameter.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index ac0b79d067e6..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,5 +0,0 @@ -import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.cpp.ir.dataflow.DataFlow2::DataFlow2 as DataFlow -} 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingParameter.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingParameter.qll deleted file mode 100644 index 2a3b69f55cd1..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingParameter.qll +++ /dev/null @@ -1,5 +0,0 @@ -import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.cpp.ir.dataflow.DataFlow3::DataFlow3 as DataFlow -} diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql index 0686c4a707c6..f6dd3b6f2126 100644 --- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql @@ -19,7 +19,6 @@ import semmle.code.cpp.security.Security import semmle.code.cpp.valuenumbering.GlobalValueNumbering import semmle.code.cpp.ir.IR import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.ir.dataflow.TaintTracking2 import semmle.code.cpp.security.FlowSources import semmle.code.cpp.models.implementations.Strcat import ExecTaint::PathGraph diff --git a/csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 000000000000..d09ec528c99e --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll b/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll index 0f22f7726202..49dd011658d4 100644 --- a/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll +++ b/csharp/ql/lib/experimental/code/csharp/Cryptography/NonCryptographicHashes.qll @@ -8,7 +8,6 @@ import csharp private import DataFlow -private import semmle.code.csharp.dataflow.TaintTracking2 predicate maybeANonCryptographicHash( Callable callable, Variable v, Expr xor, Expr mul, LoopStmt loop diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow.qll index 0fc12debaa8d..9c1c8c2fee38 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow.qll @@ -9,5 +9,5 @@ module DataFlow { private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.code.csharp.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow2.qll deleted file mode 100644 index 60525016d31a..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow2.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import csharp - -module DataFlow2 { - import semmle.code.csharp.dataflow.internal.DataFlowImpl2 -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow3.qll deleted file mode 100644 index 7f3b94694494..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow3.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import csharp - -module DataFlow3 { - import semmle.code.csharp.dataflow.internal.DataFlowImpl3 -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow4.qll deleted file mode 100644 index 29c994a2eece..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow4.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import csharp - -module DataFlow4 { - import semmle.code.csharp.dataflow.internal.DataFlowImpl4 -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow5.qll deleted file mode 100644 index 481481171660..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/DataFlow5.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import csharp - -module DataFlow5 { - import semmle.code.csharp.dataflow.internal.DataFlowImpl5 -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking.qll index fb39294ed23e..781953a8348d 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking.qll @@ -6,10 +6,9 @@ import csharp module TaintTracking { - import semmle.code.csharp.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.code.csharp.dataflow.internal.TaintTrackingPublic private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific private import semmle.code.csharp.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking import TaintFlowMake - import semmle.code.csharp.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking2.qll deleted file mode 100644 index 9ee798ed9fd5..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking2.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ - -import csharp - -module TaintTracking2 { - import semmle.code.csharp.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking3.qll deleted file mode 100644 index 476d7bf7dd77..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking3.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ - -import csharp - -module TaintTracking3 { - import semmle.code.csharp.dataflow.internal.tainttracking3.TaintTrackingImpl -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking4.qll deleted file mode 100644 index 45b8f12be5cf..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking4.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ - -import csharp - -module TaintTracking4 { - import semmle.code.csharp.dataflow.internal.tainttracking4.TaintTrackingImpl -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking5.qll deleted file mode 100644 index 7a75ce532bcb..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/TaintTracking5.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ - -import csharp - -module TaintTracking5 { - import semmle.code.csharp.dataflow.internal.tainttracking5.TaintTrackingImpl -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index 6fa484bea778..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,7 +0,0 @@ -import semmle.code.csharp.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import semmle.code.csharp.dataflow.DataFlow::DataFlow as DataFlow - import semmle.code.csharp.dataflow.internal.DataFlowImpl as DataFlowInternal - import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -} 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index 6a8fa23ef31c..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.csharp.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import semmle.code.csharp.dataflow.DataFlow2::DataFlow2 as DataFlow - import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -} 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingParameter.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingParameter.qll deleted file mode 100644 index 6c73b6ceda63..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.csharp.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import semmle.code.csharp.dataflow.DataFlow3::DataFlow3 as DataFlow - import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -} 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingParameter.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingParameter.qll deleted file mode 100644 index e394e27a50c2..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.csharp.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import semmle.code.csharp.dataflow.DataFlow4::DataFlow4 as DataFlow - import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -} 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingParameter.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingParameter.qll deleted file mode 100644 index 2668be3b376e..000000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.csharp.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import semmle.code.csharp.dataflow.DataFlow5::DataFlow5 as DataFlow - import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -} diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll index f0666b921b20..6cef58990b05 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll @@ -5,7 +5,6 @@ import csharp private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.Text -private import semmle.code.csharp.dataflow.DataFlow2 /** A method that formats a string, for example `string.Format()`. */ class FormatMethod extends Method { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll index b3b85299c69d..75f72352deb6 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll @@ -6,7 +6,6 @@ private import semmle.code.csharp.frameworks.system.data.SqlClient private import semmle.code.csharp.frameworks.EntityFramework private import semmle.code.csharp.frameworks.NHibernate private import semmle.code.csharp.frameworks.Dapper -private import semmle.code.csharp.dataflow.DataFlow4 /** An expression containing a SQL command. */ abstract class SqlExpr extends Expr { diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll index 0644e75c3df9..c0edf9e110e1 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Xml.qll @@ -2,7 +2,6 @@ import csharp private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.dataflow.DataFlow3 /** The `System.Xml` namespace. */ class SystemXmlNamespace extends Namespace { diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll index 5addc03bd88b..94dbf1d4cdcc 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ReDoSQuery.qll @@ -4,7 +4,6 @@ */ import csharp -private import semmle.code.csharp.dataflow.DataFlow2 private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources private import semmle.code.csharp.frameworks.system.text.RegularExpressions diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll index 009e1ab73c1d..5d9d18dcbac6 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll @@ -5,7 +5,6 @@ import csharp private import semmle.code.csharp.serialization.Deserializers -private import semmle.code.csharp.dataflow.TaintTracking2 private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks private import semmle.code.csharp.security.dataflow.flowsources.FlowSources diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll index 81029cc6572e..2d687b51d67a 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll @@ -7,8 +7,6 @@ import csharp private import XSSSinks private import semmle.code.csharp.security.Sanitizers private import semmle.code.csharp.security.dataflow.flowsources.FlowSources -private import semmle.code.csharp.dataflow.DataFlow2 -private import semmle.code.csharp.dataflow.TaintTracking2 /** * Holds if there is tainted flow from `source` to `sink` that may lead to a diff --git a/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll index ba98888fa6fc..1abeaf797b00 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll @@ -150,8 +150,6 @@ module XmlSettings { /** Provides predicates related to `System.Xml.XmlReader`. */ module XmlReader { - private import semmle.code.csharp.dataflow.DataFlow2 - private class InsecureXmlReaderCreate extends InsecureXmlProcessing, MethodCall { InsecureXmlReaderCreate() { this.getTarget().hasFullyQualifiedName("System.Xml.XmlReader", "Create") diff --git a/csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll b/csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll index 928cf3bdc4f4..401944adcc47 100644 --- a/csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll +++ b/csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll @@ -114,61 +114,6 @@ Expr getAValueForProp(ObjectCreation create, Assignment a, string prop) { */ predicate isPropertySet(ObjectCreation oc, string prop) { exists(getAValueForProp(oc, _, prop)) } -/** - * Tracks if a callback used in `OnAppendCookie` sets a cookie property to `true`. - */ -abstract deprecated private class OnAppendCookieTrackingConfig extends DataFlow::Configuration { - bindingset[this] - OnAppendCookieTrackingConfig() { any() } - - /** - * Specifies the cookie property name to track. - */ - abstract string propertyName(); - - override predicate isSource(DataFlow::Node source) { - exists(PropertyWrite pw, Assignment delegateAssign, Callable c | - pw.getProperty().getName() = "OnAppendCookie" and - pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreBuilderCookiePolicyOptions and - delegateAssign.getLValue() = pw and - ( - exists(LambdaExpr lambda | - delegateAssign.getRValue() = lambda and - lambda = c - ) - or - exists(DelegateCreation delegate | - delegateAssign.getRValue() = delegate and - delegate.getArgument().(CallableAccess).getTarget() = c - ) - ) and - c.getParameter(0) = source.asParameter() - ) - } - - override predicate isSink(DataFlow::Node sink) { - exists(PropertyWrite pw, Assignment a | - pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieOptions and - pw.getProperty().getName() = this.propertyName() and - a.getLValue() = pw and - exists(Expr val | - DataFlow::localExprFlow(val, a.getRValue()) and - val.getValue() = "true" - ) and - sink.asExpr() = pw.getQualifier() - ) - } - - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - node2.asExpr() = - any(PropertyRead pr | - pr.getQualifier() = node1.asExpr() and - pr.getProperty().getDeclaringType() instanceof - MicrosoftAspNetCoreCookiePolicyAppendCookieContext - ) - } -} - private signature string propertyName(); /** diff --git a/go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 000000000000..d09ec528c99e --- /dev/null +++ b/go/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/go/ql/lib/go.qll b/go/ql/lib/go.qll index fb59790dcc53..8d3955e4dad4 100644 --- a/go/ql/lib/go.qll +++ b/go/ql/lib/go.qll @@ -25,11 +25,9 @@ import semmle.go.controlflow.BasicBlocks import semmle.go.controlflow.ControlFlowGraph import semmle.go.controlflow.IR import semmle.go.dataflow.DataFlow -import semmle.go.dataflow.DataFlow2 import semmle.go.dataflow.GlobalValueNumbering import semmle.go.dataflow.SSA import semmle.go.dataflow.TaintTracking -import semmle.go.dataflow.TaintTracking2 import semmle.go.frameworks.Afero import semmle.go.frameworks.AwsLambda import semmle.go.frameworks.Beego diff --git a/go/ql/lib/semmle/go/dataflow/DataFlow.qll b/go/ql/lib/semmle/go/dataflow/DataFlow.qll index 9363bc93abda..c26adbfd2c2d 100644 --- a/go/ql/lib/semmle/go/dataflow/DataFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/DataFlow.qll @@ -25,7 +25,7 @@ module DataFlow { private import semmle.go.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.go.dataflow.internal.DataFlowImpl1 + import Public import Properties } diff --git a/go/ql/lib/semmle/go/dataflow/DataFlow2.qll b/go/ql/lib/semmle/go/dataflow/DataFlow2.qll deleted file mode 100644 index a2bae8bd9398..000000000000 --- a/go/ql/lib/semmle/go/dataflow/DataFlow2.qll +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Provides a library for local (intra-procedural) and global (inter-procedural) - * data flow analysis: deciding whether data can flow from a _source_ to a - * _sink_. - * - * Unless configured otherwise, _flow_ means that the exact value of - * the source may reach the sink. We do not track flow across pointer - * dereferences or array indexing. To track these types of flow, where the - * exact value may not be preserved, import - * `semmle.code.go.dataflow.TaintTracking`. - * - * To use global (interprocedural) data flow, extend the class - * `DataFlow::Configuration` as documented on that class. To use local - * (intraprocedural) data flow, invoke `DataFlow::localFlow` or - * `DataFlow::LocalFlowStep` with arguments of type `DataFlow::Node`. - */ - -import go - -/** - * Provides a library for local (intra-procedural) and global (inter-procedural) - * data flow analysis. - */ -module DataFlow2 { - import semmle.go.dataflow.internal.DataFlowImpl2 - import Properties -} diff --git a/go/ql/lib/semmle/go/dataflow/TaintTracking.qll b/go/ql/lib/semmle/go/dataflow/TaintTracking.qll index d762e925ab57..c469574b3b9e 100644 --- a/go/ql/lib/semmle/go/dataflow/TaintTracking.qll +++ b/go/ql/lib/semmle/go/dataflow/TaintTracking.qll @@ -10,11 +10,10 @@ import semmle.go.dataflow.DataFlow * global (inter-procedural) taint-tracking analyses. */ module TaintTracking { - import semmle.go.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.go.dataflow.internal.TaintTrackingUtil private import semmle.go.dataflow.internal.DataFlowImplSpecific private import semmle.go.dataflow.internal.TaintTrackingImplSpecific private import semmle.go.Locations private import codeql.dataflow.TaintTracking import TaintFlowMake - import semmle.go.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/go/ql/lib/semmle/go/dataflow/TaintTracking2.qll b/go/ql/lib/semmle/go/dataflow/TaintTracking2.qll deleted file mode 100644 index 6b1b2487e5b4..000000000000 --- a/go/ql/lib/semmle/go/dataflow/TaintTracking2.qll +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking2 { - import semmle.go.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd261..000000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index a5a45514a062..000000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.go.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.go.dataflow.DataFlow::DataFlow as DataFlow - import semmle.go.dataflow.internal.DataFlowImpl as DataFlowInternal -} diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd261..000000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingParameter.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index 1130c2e42e1f..000000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,5 +0,0 @@ -import semmle.go.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.go.dataflow.DataFlow2::DataFlow2 as DataFlow -} diff --git a/go/ql/lib/semmle/go/security/CleartextLogging.qll b/go/ql/lib/semmle/go/security/CleartextLogging.qll index 7c29f0ba130e..2e0c9665c4b6 100644 --- a/go/ql/lib/semmle/go/security/CleartextLogging.qll +++ b/go/ql/lib/semmle/go/security/CleartextLogging.qll @@ -16,49 +16,6 @@ import go module CleartextLogging { import CleartextLoggingCustomizations::CleartextLogging - /** - * DEPRECATED: Use `Flow` instead. - * - * A data-flow tracking configuration for clear-text logging of sensitive information. - * - * This configuration identifies flows from `Source`s, which are sources of - * sensitive data, to `Sink`s, which is an abstract class representing all - * the places sensitive data may be stored in cleartext. Additional sources or sinks can be - * added either by extending the relevant class, or by subclassing this configuration itself, - * and amending the sources and sinks. - */ - deprecated class Configuration extends DataFlow::Configuration { - Configuration() { this = "CleartextLogging" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isBarrier(DataFlow::Node node) { - node instanceof Barrier - or - exists(DataFlow::CallNode call | node = call.getResult() | - call.getTarget() = Builtin::error().getType().getMethod("Error") - or - call.getTarget().(Method).hasQualifiedName("fmt", "Stringer", "String") - ) - } - - override predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) { - // A taint propagating data-flow edge through structs: a tainted write taints the entire struct. - exists(Write write | - write.writesField(trg.(DataFlow::PostUpdateNode).getPreUpdateNode(), _, src) - ) - or - // taint steps that do not include flow through fields. Field reads would produce FPs due to - // the additional taint step above that taints whole structs from individual field writes. - TaintTracking::localTaintStep(src, trg) and - not TaintTracking::fieldReadStep(src, trg) and - // Also exclude protobuf field fetches, since they amount to single field reads. - not any(Protobuf::GetMethod gm).taintStep(src, trg) - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll index 68d874768ce5..3c6cddc427f8 100644 --- a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll +++ b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll @@ -53,132 +53,6 @@ int getIntTypeBitSize(File file, int architectureSpecificBitSize) { result = architectureSpecificBitSize } -/** - * Holds if converting from an integer types with size `sourceBitSize` to - * one with size `sinkBitSize` can produce unexpected values, where 0 means - * architecture-dependent. - * - * Architecture-dependent bit sizes can be 32 or 64. To catch flows that - * only manifest on 64-bit architectures we consider an - * architecture-dependent source bit size to be 64. To catch flows that - * only happen on 32-bit architectures we consider an - * architecture-dependent sink bit size to be 32. We exclude the case where - * both source and sink have architecture-dependent bit sizes. - */ -private predicate isIncorrectIntegerConversion(int sourceBitSize, int sinkBitSize) { - sourceBitSize in [16, 32, 64] and - sinkBitSize in [8, 16, 32] and - sourceBitSize > sinkBitSize - or - // Treat `sourceBitSize = 0` like `sourceBitSize = 64`, and exclude `sinkBitSize = 0` - sourceBitSize = 0 and - sinkBitSize in [8, 16, 32] - or - // Treat `sinkBitSize = 0` like `sinkBitSize = 32`, and exclude `sourceBitSize = 0` - sourceBitSize = 64 and - sinkBitSize = 0 -} - -/** - * DEPRECATED: use `Flow` instead. - * - * A taint-tracking configuration for reasoning about when an integer - * obtained from parsing a string flows to a type conversion to a smaller - * integer types, which could cause unexpected values. - */ -deprecated class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration { - boolean sinkIsSigned; - int sourceBitSize; - int sinkBitSize; - - ConversionWithoutBoundsCheckConfig() { - sinkIsSigned in [true, false] and - isIncorrectIntegerConversion(sourceBitSize, sinkBitSize) and - this = "ConversionWithoutBoundsCheckConfig" + sourceBitSize + sinkIsSigned + sinkBitSize - } - - /** Gets the bit size of the source. */ - int getSourceBitSize() { result = sourceBitSize } - - override predicate isSource(DataFlow::Node source) { - exists( - DataFlow::CallNode c, IntegerParser::Range ip, int apparentBitSize, int effectiveBitSize - | - c.getTarget() = ip and source = c.getResult(0) - | - ( - apparentBitSize = ip.getTargetBitSize() - or - // If we are reading a variable, check if it is - // `strconv.IntSize`, and use 0 if it is. - exists(DataFlow::Node rawBitSize | rawBitSize = ip.getTargetBitSizeInput().getNode(c) | - if rawBitSize = any(Strconv::IntSize intSize).getARead() - then apparentBitSize = 0 - else apparentBitSize = rawBitSize.getIntValue() - ) - ) and - ( - if apparentBitSize = 0 - then effectiveBitSize = getIntTypeBitSize(source.getFile(), 0) - else effectiveBitSize = apparentBitSize - ) and - // `effectiveBitSize` could be any value between 0 and 64, but we - // can round it up to the nearest size of an integer type without - // changing behavior. - sourceBitSize = min(int b | b in [0, 8, 16, 32, 64] and b >= effectiveBitSize) - ) - } - - /** - * Holds if `sink` is a typecast to an integer type with size `bitSize` (where - * 0 represents architecture-dependent) and the expression being typecast is - * not also in a right-shift expression. We allow this case because it is - * a common pattern to serialise `byte(v)`, `byte(v >> 8)`, and so on. - */ - predicate isSinkWithBitSize(DataFlow::TypeCastNode sink, int bitSize) { - sink.asExpr() instanceof ConversionExpr and - exists(IntegerType integerType | sink.getResultType().getUnderlyingType() = integerType | - ( - bitSize = integerType.getSize() - or - not exists(integerType.getSize()) and - bitSize = getIntTypeBitSize(sink.getFile(), 0) - ) and - if integerType instanceof SignedIntegerType then sinkIsSigned = true else sinkIsSigned = false - ) and - not exists(ShrExpr shrExpr | - shrExpr.getLeftOperand().getGlobalValueNumber() = - sink.getOperand().asExpr().getGlobalValueNumber() or - shrExpr.getLeftOperand().(AndExpr).getAnOperand().getGlobalValueNumber() = - sink.getOperand().asExpr().getGlobalValueNumber() - ) - } - - override predicate isSink(DataFlow::Node sink) { - // We use the argument of the type conversion as the configuration sink so that we - // can sanitize the result of the conversion to prevent flow on to further sinks - // without needing to use `isSanitizerOut`, which doesn't work with flow states - // (and therefore the legacy `TaintTracking::Configuration` class). - this.isSinkWithBitSize(sink.getASuccessor(), sinkBitSize) - } - - override predicate isSanitizer(DataFlow::Node node) { - // To catch flows that only happen on 32-bit architectures we - // consider an architecture-dependent sink bit size to be 32. - exists(UpperBoundCheckGuard g, int bitSize | - if sinkBitSize != 0 then bitSize = sinkBitSize else bitSize = 32 - | - node = DataFlow::BarrierGuard::getABarrierNodeForGuard(g) and - if sinkIsSigned = true then g.isBoundFor(bitSize, 32) else g.isBoundFor(bitSize - 1, 32) - ) - or - exists(int bitSize | - isIncorrectIntegerConversion(sourceBitSize, bitSize) and - this.isSinkWithBitSize(node, bitSize) - ) - } -} - private int validBitSize() { result = [7, 8, 15, 16, 31, 32, 63, 64] } private newtype TArchitectureBitSize = diff --git a/go/ql/lib/semmle/go/security/InsecureRandomness.qll b/go/ql/lib/semmle/go/security/InsecureRandomness.qll index 675f0b4b9a2d..83746f7b96ed 100644 --- a/go/ql/lib/semmle/go/security/InsecureRandomness.qll +++ b/go/ql/lib/semmle/go/security/InsecureRandomness.qll @@ -16,25 +16,6 @@ import go module InsecureRandomness { import InsecureRandomnessCustomizations::InsecureRandomness - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about random values that are - * not cryptographically secure. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "InsecureRandomness" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { this.isSinkWithKind(sink, _) } - - /** Holds if `sink` is a sink for this configuration with kind `kind`. */ - predicate isSinkWithKind(Sink sink, string kind) { kind = sink.getKind() } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - } - /** Holds if `sink` is a sink for this configuration with kind `kind`. */ predicate isSinkWithKind(Sink sink, string kind) { kind = sink.getKind() } diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll index d3576f005b9c..bfe47f260cd6 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirect.qll @@ -17,51 +17,6 @@ import UrlConcatenation module OpenUrlRedirect { import OpenUrlRedirectCustomizations::OpenUrlRedirect - /** - * DEPRECATED: Use `Flow` instead. - * - * A data-flow configuration for reasoning about unvalidated URL redirections. - */ - deprecated class Configuration extends DataFlow::Configuration { - Configuration() { this = "OpenUrlRedirect" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isBarrier(DataFlow::Node node) { node instanceof Barrier } - - override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { - // taint steps that do not include flow through fields - TaintTracking::localTaintStep(pred, succ) and not TaintTracking::fieldReadStep(pred, succ) - or - // explicit extra taint steps for this query - any(AdditionalStep s).hasTaintStep(pred, succ) - or - // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, pred) and succ = v.getAUse() - ) - or - // propagate out of most URL fields, but not `ForceQuery` and `Scheme` - exists(Field f, string fn | - f.hasQualifiedName("net/url", "URL", fn) and - not fn in ["ForceQuery", "Scheme"] - | - succ.(Read).readsField(pred, f) - ) - } - - override predicate isBarrierOut(DataFlow::Node node) { - // block propagation of this unsafe value when its host is overwritten - exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(node.getASuccessor(), f, _) - ) - or - hostnameSanitizingPrefixEdge(node, _) - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/ReflectedXss.qll b/go/ql/lib/semmle/go/security/ReflectedXss.qll index a605d78633d7..1068c6fae3d1 100644 --- a/go/ql/lib/semmle/go/security/ReflectedXss.qll +++ b/go/ql/lib/semmle/go/security/ReflectedXss.qll @@ -16,24 +16,6 @@ import go module ReflectedXss { import ReflectedXssCustomizations::ReflectedXss - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about XSS. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ReflectedXss" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/RequestForgery.qll b/go/ql/lib/semmle/go/security/RequestForgery.qll index 5f7139a1b44a..bdf26a1f18fe 100644 --- a/go/ql/lib/semmle/go/security/RequestForgery.qll +++ b/go/ql/lib/semmle/go/security/RequestForgery.qll @@ -16,36 +16,6 @@ import go module RequestForgery { import RequestForgeryCustomizations::RequestForgery - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about request forgery. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "RequestForgery" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, pred) and succ = v.getAUse() - ) - } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - - override predicate isSanitizerOut(DataFlow::Node node) { - super.isSanitizerOut(node) or - node instanceof SanitizerEdge - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll index f4d1a535badd..d74e2156a609 100644 --- a/go/ql/lib/semmle/go/security/SafeUrlFlow.qll +++ b/go/ql/lib/semmle/go/security/SafeUrlFlow.qll @@ -16,35 +16,6 @@ import go module SafeUrlFlow { import SafeUrlFlowCustomizations::SafeUrlFlow - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about safe URLs. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SafeUrlFlow" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, pred) and succ = v.getAUse() - ) - } - - override predicate isSanitizerOut(DataFlow::Node node) { - // block propagation of this safe value when its host is overwritten - exists(Write w, Field f | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(node.getASuccessor(), f, _) - ) - or - node instanceof SanitizerEdge - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/SqlInjection.qll b/go/ql/lib/semmle/go/security/SqlInjection.qll index 366a05cf3df7..e24b30f40d38 100644 --- a/go/ql/lib/semmle/go/security/SqlInjection.qll +++ b/go/ql/lib/semmle/go/security/SqlInjection.qll @@ -13,28 +13,6 @@ import go module SqlInjection { import SqlInjectionCustomizations::SqlInjection - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about SQL-injection vulnerabilities. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SqlInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - NoSql::isAdditionalMongoTaintStep(pred, succ) - } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/StoredCommand.qll b/go/ql/lib/semmle/go/security/StoredCommand.qll index 4c21a292371e..38555370cfcc 100644 --- a/go/ql/lib/semmle/go/security/StoredCommand.qll +++ b/go/ql/lib/semmle/go/security/StoredCommand.qll @@ -16,28 +16,6 @@ import CommandInjectionCustomizations * injection vulnerabilities. */ module StoredCommand { - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about command-injection vulnerabilities. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "StoredCommand" } - - override predicate isSource(DataFlow::Node source) { - source instanceof StoredXss::Source and - // exclude file names, since those are not generally an issue - not source instanceof StoredXss::FileNameSource - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof CommandInjection::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof CommandInjection::Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof StoredXss::Source and diff --git a/go/ql/lib/semmle/go/security/StoredXss.qll b/go/ql/lib/semmle/go/security/StoredXss.qll index 37e4b0489104..2bf6bf248048 100644 --- a/go/ql/lib/semmle/go/security/StoredXss.qll +++ b/go/ql/lib/semmle/go/security/StoredXss.qll @@ -16,24 +16,6 @@ import go module StoredXss { import StoredXssCustomizations::StoredXss - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about XSS. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "StoredXss" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/StringBreak.qll b/go/ql/lib/semmle/go/security/StringBreak.qll index fed3b9b14438..02b4c5b3313b 100644 --- a/go/ql/lib/semmle/go/security/StringBreak.qll +++ b/go/ql/lib/semmle/go/security/StringBreak.qll @@ -13,27 +13,6 @@ import go module StringBreak { import StringBreakCustomizations::StringBreak - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about unsafe-quoting vulnerabilities, - * parameterized with the type of quote being tracked. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Quote quote; - - Configuration() { this = "StringBreak" + quote } - - /** Gets the type of quote being tracked by this configuration. */ - Quote getQuote() { result = quote } - - override predicate isSource(DataFlow::Node nd) { nd instanceof Source } - - override predicate isSink(DataFlow::Node nd) { quote = nd.(Sink).getQuote() } - - override predicate isSanitizer(DataFlow::Node nd) { quote = nd.(Sanitizer).getQuote() } - } - private module Config implements DataFlow::StateConfigSig { /** The flow state that we track is the type of quote used. */ class FlowState = Quote; diff --git a/go/ql/lib/semmle/go/security/TaintedPath.qll b/go/ql/lib/semmle/go/security/TaintedPath.qll index 26009554c249..674cda1157cf 100644 --- a/go/ql/lib/semmle/go/security/TaintedPath.qll +++ b/go/ql/lib/semmle/go/security/TaintedPath.qll @@ -11,24 +11,6 @@ import go module TaintedPath { import TaintedPathCustomizations::TaintedPath - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about path-traversal vulnerabilities. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "TaintedPath" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll b/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll index 2b969ffc4d95..1d18ac5f639a 100644 --- a/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll +++ b/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll @@ -13,24 +13,6 @@ import go module UnsafeUnzipSymlink { import UnsafeUnzipSymlinkCustomizations::UnsafeUnzipSymlink - /** - * DEPRECATED: Use copies of `EvalSymlinksConfig` and `EvalSymlinksFlow` instead. - * - * A taint-flow configuration tracking archive header fields flowing to a `path/filepath.EvalSymlinks` call. - */ - deprecated class EvalSymlinksConfiguration extends TaintTracking2::Configuration { - EvalSymlinksConfiguration() { this = "Archive header field symlinks resolved" } - - override predicate isSource(DataFlow::Node source) { source instanceof FilenameWithSymlinks } - - override predicate isSink(DataFlow::Node sink) { sink instanceof EvalSymlinksSink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof EvalSymlinksInvalidator - } - } - // Archive header field symlinks resolved private module EvalSymlinksConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof FilenameWithSymlinks } @@ -53,28 +35,6 @@ module UnsafeUnzipSymlink { EvalSymlinksFlow::flow(getASimilarReadNode(node), _) } - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-flow configuration tracking archive header fields flowing to an `os.Symlink` call, - * which never flow to a `path/filepath.EvalSymlinks` call. - */ - deprecated class SymlinkConfiguration extends TaintTracking::Configuration { - SymlinkConfiguration() { this = "Unsafe unzipping of symlinks" } - - override predicate isSource(DataFlow::Node source) { - source instanceof FilenameWithSymlinks and - not symlinksEvald(source) - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof SymlinkSink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof SymlinkSanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof FilenameWithSymlinks and diff --git a/go/ql/lib/semmle/go/security/XPathInjection.qll b/go/ql/lib/semmle/go/security/XPathInjection.qll index 2e374dfbf246..61bd00977daf 100644 --- a/go/ql/lib/semmle/go/security/XPathInjection.qll +++ b/go/ql/lib/semmle/go/security/XPathInjection.qll @@ -13,24 +13,6 @@ import go module XPathInjection { import XPathInjectionCustomizations::XPathInjection - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about untrusted user input used in an XPath expression. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "XPathInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/lib/semmle/go/security/ZipSlip.qll b/go/ql/lib/semmle/go/security/ZipSlip.qll index 4a7ba231f0fc..f16daf84c3dd 100644 --- a/go/ql/lib/semmle/go/security/ZipSlip.qll +++ b/go/ql/lib/semmle/go/security/ZipSlip.qll @@ -11,24 +11,6 @@ import go module ZipSlip { import ZipSlipCustomizations::ZipSlip - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about zip-slip vulnerabilities. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ZipSlip" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/src/Security/CWE-640/EmailInjection.qll b/go/ql/src/Security/CWE-640/EmailInjection.qll index 479fe6dc0555..35b7795ad55f 100644 --- a/go/ql/src/Security/CWE-640/EmailInjection.qll +++ b/go/ql/src/Security/CWE-640/EmailInjection.qll @@ -16,19 +16,6 @@ import go module EmailInjection { import EmailInjectionCustomizations::EmailInjection - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about email-injection vulnerabilities. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "Email Injection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/src/experimental/CWE-090/LDAPInjection.qll b/go/ql/src/experimental/CWE-090/LDAPInjection.qll index 4e0a6e290dab..fd138fa06458 100644 --- a/go/ql/src/experimental/CWE-090/LDAPInjection.qll +++ b/go/ql/src/experimental/CWE-090/LDAPInjection.qll @@ -95,22 +95,6 @@ private class LdapClientDNSink extends LdapSink { } } -/** - * DEPRECATED: Use `LdapInjectionFlow` instead. - * - * A taint-tracking configuration for reasoning about when a `ActiveThreatModelSource` - * flows into an argument or field that is vulnerable to LDAP injection. - */ -deprecated class LdapInjectionConfiguration extends TaintTracking::Configuration { - LdapInjectionConfiguration() { this = "Ldap injection" } - - override predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource } - - override predicate isSink(DataFlow::Node sink) { sink instanceof LdapSink } - - override predicate isSanitizer(DataFlow::Node sanitizer) { sanitizer instanceof LdapSanitizer } -} - private module LdapInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource } diff --git a/go/ql/src/experimental/CWE-1004/AuthCookie.qll b/go/ql/src/experimental/CWE-1004/AuthCookie.qll index c995a8b2f688..411da5a79fa0 100644 --- a/go/ql/src/experimental/CWE-1004/AuthCookie.qll +++ b/go/ql/src/experimental/CWE-1004/AuthCookie.qll @@ -64,28 +64,6 @@ private class SetCookieSink extends DataFlow::Node { } } -/** - * DEPRECATED: Use `NameToNetHttpCookieTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from sensitive names to - * `net/http.SetCookie`. - */ -deprecated class NameToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration { - NameToNetHttpCookieTrackingConfiguration() { this = "NameToNetHttpCookieTrackingConfiguration" } - - override predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) } - - override predicate isSink(DataFlow::Node sink) { sink instanceof SetCookieSink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(StructLit sl | - sl.getType() instanceof NetHttpCookieType and - getValueForFieldWrite(sl, "Name") = pred and - sl = succ.asExpr() - ) - } -} - private module NameToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) } @@ -103,30 +81,6 @@ private module NameToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig /** Tracks taint flow from sensitive names to `net/http.SetCookie`. */ module NameToNetHttpCookieTrackingFlow = TaintTracking::Global; -/** - * DEPRECATED: Use `BoolToNetHttpCookieTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from `bool` assigned to - * `HttpOnly` that flows into `net/http.SetCookie`. - */ -deprecated class BoolToNetHttpCookieTrackingConfiguration extends TaintTracking::Configuration { - BoolToNetHttpCookieTrackingConfiguration() { this = "BoolToNetHttpCookieTrackingConfiguration" } - - override predicate isSource(DataFlow::Node source) { - source.getType().getUnderlyingType() instanceof BoolType - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof SetCookieSink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(StructLit sl | - sl.getType() instanceof NetHttpCookieType and - getValueForFieldWrite(sl, "HttpOnly") = pred and - sl = succ.asExpr() - ) - } -} - private module BoolToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.getType().getUnderlyingType() instanceof BoolType @@ -149,29 +103,6 @@ private module BoolToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig */ module BoolToNetHttpCookieTrackingFlow = TaintTracking::Global; -/** - * DEPRECATED: Use `BoolToGinSetCookieTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from `HttpOnly` set to - * `false` to `gin-gonic/gin.Context.SetCookie`. - */ -deprecated class BoolToGinSetCookieTrackingConfiguration extends DataFlow::Configuration { - BoolToGinSetCookieTrackingConfiguration() { this = "BoolToGinSetCookieTrackingConfiguration" } - - override predicate isSource(DataFlow::Node source) { source.getBoolValue() = false } - - override predicate isSink(DataFlow::Node sink) { - exists(DataFlow::MethodCallNode mcn | - mcn.getTarget() instanceof GinContextSetCookieMethod and - mcn.getArgument(6) = sink and - exists(NameToGinSetCookieTrackingConfiguration cfg, DataFlow::Node nameArg | - cfg.hasFlowTo(nameArg) and - mcn.getArgument(0) = nameArg - ) - ) - } -} - private module BoolToGinSetCookieTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.getBoolValue() = false } @@ -193,25 +124,6 @@ private module BoolToGinSetCookieTrackingConfig implements DataFlow::ConfigSig { */ module BoolToGinSetCookieTrackingFlow = DataFlow::Global; -/** - * DEPRECATED: Use `NameToGinSetCookieTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from sensitive names to - * `gin-gonic/gin.Context.SetCookie`. - */ -deprecated private class NameToGinSetCookieTrackingConfiguration extends DataFlow2::Configuration { - NameToGinSetCookieTrackingConfiguration() { this = "NameToGinSetCookieTrackingConfiguration" } - - override predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) } - - override predicate isSink(DataFlow::Node sink) { - exists(DataFlow::MethodCallNode mcn | - mcn.getTarget() instanceof GinContextSetCookieMethod and - mcn.getArgument(0) = sink - ) - } -} - private module NameToGinSetCookieTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) } @@ -251,39 +163,6 @@ private class GorillaStoreSaveSink extends DataFlow::Node { } } -/** - * DEPRECATED: Use `GorillaCookieStoreSaveTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from gorilla cookie store - * creation to `gorilla/sessions.Session.Save`. - */ -deprecated class GorillaCookieStoreSaveTrackingConfiguration extends DataFlow::Configuration { - GorillaCookieStoreSaveTrackingConfiguration() { - this = "GorillaCookieStoreSaveTrackingConfiguration" - } - - override predicate isSource(DataFlow::Node source) { - source - .(DataFlow::CallNode) - .getTarget() - .hasQualifiedName(package("github.com/gorilla/sessions", ""), "NewCookieStore") - } - - override predicate isSink(DataFlow::Node sink) { - sink instanceof GorillaSessionSaveSink or - sink instanceof GorillaStoreSaveSink - } - - override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(DataFlow::MethodCallNode cn | - cn.getTarget() - .hasQualifiedName(package("github.com/gorilla/sessions", ""), "CookieStore", "Get") and - pred = cn.getReceiver() and - succ = cn.getResult(0) - ) - } -} - private module GorillaCookieStoreSaveTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source @@ -313,34 +192,6 @@ private module GorillaCookieStoreSaveTrackingConfig implements DataFlow::ConfigS */ module GorillaCookieStoreSaveTrackingFlow = DataFlow::Global; -/** - * DEPRECATED: Use `GorillaSessionOptionsTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from session options to - * `gorilla/sessions.Session.Save`. - */ -deprecated class GorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration { - GorillaSessionOptionsTrackingConfiguration() { - this = "GorillaSessionOptionsTrackingConfiguration" - } - - override predicate isSource(DataFlow::Node source) { - exists(StructLit sl | - sl.getType().hasQualifiedName(package("github.com/gorilla/sessions", ""), "Options") and - source.asExpr() = sl - ) - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof GorillaSessionSaveSink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(GorillaSessionOptionsField f, DataFlow::Write w, DataFlow::Node base | - w.writesField(base, f, pred) and - succ = base - ) - } -} - private module GorillaSessionOptionsTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { exists(StructLit sl | @@ -366,37 +217,6 @@ private module GorillaSessionOptionsTrackingConfig implements DataFlow::ConfigSi module GorillaSessionOptionsTrackingFlow = TaintTracking::Global; -/** - * DEPRECATED: Use `BoolToGorillaSessionOptionsTrackingFlow` instead. - * - * A taint-tracking configuration for tracking flow from a `bool` assigned to - * `HttpOnly` to `gorilla/sessions.Session.Save`. - */ -deprecated class BoolToGorillaSessionOptionsTrackingConfiguration extends TaintTracking::Configuration -{ - BoolToGorillaSessionOptionsTrackingConfiguration() { - this = "BoolToGorillaSessionOptionsTrackingConfiguration" - } - - override predicate isSource(DataFlow::Node source) { - source.getType().getUnderlyingType() instanceof BoolType - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof GorillaSessionSaveSink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(StructLit sl | - getValueForFieldWrite(sl, "HttpOnly") = pred and - sl = succ.asExpr() - ) - or - exists(GorillaSessionOptionsField f, DataFlow::Write w, DataFlow::Node base | - w.writesField(base, f, pred) and - succ = base - ) - } -} - private module BoolToGorillaSessionOptionsTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.getType().getUnderlyingType() instanceof BoolType diff --git a/go/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll b/go/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll index 61a55bdd32bb..1d64d731f507 100644 --- a/go/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll +++ b/go/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll @@ -48,24 +48,6 @@ module WeakCryptoAlgorithm { } } - /** - * DEPRECATED: Use `Flow` instead. - * - * A configuration depicting taint flow from sensitive information to weak cryptographic algorithms. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "WeakCryptoAlgorithm" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/src/experimental/CWE-74/DsnInjectionCustomizations.qll b/go/ql/src/experimental/CWE-74/DsnInjectionCustomizations.qll index 5417ddf4f3e0..2c3208550720 100644 --- a/go/ql/src/experimental/CWE-74/DsnInjectionCustomizations.qll +++ b/go/ql/src/experimental/CWE-74/DsnInjectionCustomizations.qll @@ -6,28 +6,6 @@ import semmle.go.dataflow.barrierguardutil.RegexpCheck /** A source for `DsnInjection` taint-flow configuration. */ abstract class Source extends DataFlow::Node { } -/** - * DEPRECATED: Use `DsnInjectionFlow` instead. - * - * A taint-tracking configuration to reason about Data Source Name injection vulnerabilities. - */ -deprecated class DsnInjection extends TaintTracking::Configuration { - DsnInjection() { this = "DsnInjection" } - - override predicate isSource(DataFlow::Node node) { node instanceof Source } - - override predicate isSink(DataFlow::Node node) { - exists(DataFlow::CallNode c | - c.getTarget().hasQualifiedName("database/sql", "Open") and - c.getArgument(0).getStringValue() = "mysql" - | - node = c.getArgument(1) - ) - } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof RegexpCheckBarrier } -} - private module DsnInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll b/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll index 0d4bdfb1dd0c..2f2ca94fa87f 100644 --- a/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll +++ b/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll @@ -42,33 +42,6 @@ private class ConstComparisonExpr extends ComparisonExpr { } } -/** - * DEPRECATED: Use `Flow` instead. - * - * A data-flow configuration for reasoning about - * user-controlled bypassing of sensitive actions. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "Condtional Expression Check Bypass" } - - override predicate isSource(DataFlow::Node source) { - source instanceof ActiveThreatModelSource - or - exists(DataFlow::FieldReadNode f | - f.getField().hasQualifiedName("net/http", "Request", "Host") - | - source = f - ) - } - - override predicate isSink(DataFlow::Node sink) { - exists(ConstComparisonExpr c | - c.getAnOperand() = sink.asExpr() and - not c.isPotentialFalsePositive() - ) - } -} - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource diff --git a/go/ql/src/experimental/CWE-918/SSRF.qll b/go/ql/src/experimental/CWE-918/SSRF.qll index 42b017ac487d..b1374da8a5f7 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.qll +++ b/go/ql/src/experimental/CWE-918/SSRF.qll @@ -15,36 +15,6 @@ module ServerSideRequestForgery { private import semmle.go.dataflow.barrierguardutil.RegexpCheck private import semmle.go.dataflow.Properties - /** - * DEPRECATED: Use `Flow` instead. - * - * A taint-tracking configuration for reasoning about request forgery. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SSRF" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - // propagate to a URL when its host is assigned to - exists(Write w, Field f, SsaWithFields v | f.hasQualifiedName("net/url", "URL", "Host") | - w.writesField(v.getAUse(), f, pred) and succ = v.getAUse() - ) - } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } - - override predicate isSanitizerOut(DataFlow::Node node) { - super.isSanitizerOut(node) or - node instanceof SanitizerEdge - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 000000000000..d09ec528c99e --- /dev/null +++ b/java/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow.qll index 66a7a847c336..ab48577c02e7 100644 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/DataFlow.qll @@ -9,5 +9,5 @@ module DataFlow { private import semmle.code.java.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import semmle.code.java.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow2.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow2.qll deleted file mode 100644 index 92003314778a..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow2.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import java - -module DataFlow2 { - import semmle.code.java.dataflow.internal.DataFlowImpl2 -} diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow3.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow3.qll deleted file mode 100644 index c8d614e08793..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow3.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import java - -module DataFlow3 { - import semmle.code.java.dataflow.internal.DataFlowImpl3 -} diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow4.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow4.qll deleted file mode 100644 index 852cfd9f813e..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow4.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import java - -module DataFlow4 { - import semmle.code.java.dataflow.internal.DataFlowImpl4 -} diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow5.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow5.qll deleted file mode 100644 index f8986a03524d..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow5.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import java - -module DataFlow5 { - import semmle.code.java.dataflow.internal.DataFlowImpl5 -} diff --git a/java/ql/lib/semmle/code/java/dataflow/DataFlow6.qll b/java/ql/lib/semmle/code/java/dataflow/DataFlow6.qll deleted file mode 100644 index 28fa11da475f..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/DataFlow6.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ - -import java - -module DataFlow6 { - import semmle.code.java.dataflow.internal.DataFlowImpl6 -} diff --git a/java/ql/lib/semmle/code/java/dataflow/TaintTracking.qll b/java/ql/lib/semmle/code/java/dataflow/TaintTracking.qll index ed13837a312b..e62850fbc389 100644 --- a/java/ql/lib/semmle/code/java/dataflow/TaintTracking.qll +++ b/java/ql/lib/semmle/code/java/dataflow/TaintTracking.qll @@ -4,14 +4,12 @@ */ import semmle.code.java.dataflow.DataFlow -import semmle.code.java.dataflow.DataFlow2 import semmle.code.java.dataflow.internal.TaintTrackingUtil::StringBuilderVarModule module TaintTracking { - import semmle.code.java.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.code.java.dataflow.internal.TaintTrackingUtil private import semmle.code.java.dataflow.internal.DataFlowImplSpecific private import semmle.code.java.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking import TaintFlowMake - import semmle.code.java.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/java/ql/lib/semmle/code/java/dataflow/TaintTracking2.qll b/java/ql/lib/semmle/code/java/dataflow/TaintTracking2.qll deleted file mode 100644 index abd909dba2bd..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/TaintTracking2.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking2 { - import semmle.code.java.dataflow.internal.tainttracking2.TaintTrackingImpl -} diff --git a/java/ql/lib/semmle/code/java/dataflow/TaintTracking3.qll b/java/ql/lib/semmle/code/java/dataflow/TaintTracking3.qll deleted file mode 100644 index 49c43ed1418c..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/TaintTracking3.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking3 { - import semmle.code.java.dataflow.internal.tainttracking3.TaintTrackingImpl -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index 2608adffda33..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.code.java.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.java.dataflow.DataFlow::DataFlow as DataFlow - import semmle.code.java.dataflow.internal.DataFlowImpl as DataFlowInternal -} 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingParameter.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index 5a9c924b6bd6..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,5 +0,0 @@ -import semmle.code.java.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.java.dataflow.DataFlow2::DataFlow2 as DataFlow -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd261..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingParameter.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingParameter.qll deleted file mode 100644 index 10fb6b09fa83..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingParameter.qll +++ /dev/null @@ -1,5 +0,0 @@ -import semmle.code.java.dataflow.internal.TaintTrackingUtil as Public - -module Private { - import semmle.code.java.dataflow.DataFlow3::DataFlow3 as DataFlow -} diff --git a/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll b/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll index d40e7ebf81e9..85f3a5ef06bb 100644 --- a/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll +++ b/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll @@ -5,8 +5,6 @@ import java import semmle.code.java.Maps import semmle.code.java.dataflow.DataFlow -deprecated import semmle.code.java.dataflow.DataFlow2 -private import semmle.code.java.dataflow.DataFlow2 /** * The class `com.cedarsoftware.util.io.JsonReader`. diff --git a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll index 109300458d29..7625f9d7da48 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll @@ -2,9 +2,7 @@ import java import semmle.code.java.dataflow.FlowSources -deprecated import semmle.code.java.dataflow.DataFlow2 import semmle.code.java.dataflow.TaintTracking -deprecated import semmle.code.java.dataflow.TaintTracking3 import semmle.code.java.security.AndroidIntentRedirection /** A taint tracking configuration for tainted Intents being used to start Android components. */ diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll index a36a4754584a..1f262ad57d61 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll @@ -2,7 +2,6 @@ import java import semmle.code.java.dataflow.DataFlow -deprecated import semmle.code.java.dataflow.DataFlow3 import semmle.code.java.security.CleartextStorageQuery private import semmle.code.java.dataflow.FlowSinks private import semmle.code.java.dataflow.FlowSources diff --git a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCallQuery.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCallQuery.qll index 2192c5c70de2..06d7869ce996 100644 --- a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCallQuery.qll +++ b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCallQuery.qll @@ -4,8 +4,6 @@ import java import semmle.code.java.dataflow.DataFlow -deprecated import semmle.code.java.dataflow.DataFlow2 -private import semmle.code.java.dataflow.DataFlow2 import HardcodedCredentials /** diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index a5d8f256b036..650527e88e45 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -26,24 +26,10 @@ class NoState extends PendingIntentState, TNoState { } /** A source for an implicit `PendingIntent` flow. */ -abstract class ImplicitPendingIntentSource extends ApiSourceNode { - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if this source has the specified `state`. - */ - deprecated predicate hasState(DataFlow::FlowState state) { state = "" } -} +abstract class ImplicitPendingIntentSource extends ApiSourceNode { } /** A sink that sends an implicit and mutable `PendingIntent` to a third party. */ -abstract class ImplicitPendingIntentSink extends DataFlow::Node { - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if this sink has the specified `state`. - */ - deprecated predicate hasState(DataFlow::FlowState state) { state = "" } -} +abstract class ImplicitPendingIntentSink extends DataFlow::Node { } /** * A unit class for adding additional taint steps. @@ -62,21 +48,6 @@ class ImplicitPendingIntentAdditionalTaintStep extends Unit { * Holds if the step from `node1` to `node2` creates a mutable `PendingIntent`. */ predicate mutablePendingIntentCreation(DataFlow::Node node1, DataFlow::Node node2) { none() } - - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * Use `mutablePendingIntentCreation` instead. - * - * Holds if the step from `node1` to `node2` should be considered a taint - * step for flows related to the use of implicit `PendingIntent`s. This step is only applicable - * in `state1` and updates the flow state to `state2`. - */ - deprecated predicate step( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } } private class IntentCreationSource extends ImplicitPendingIntentSource { diff --git a/java/ql/lib/semmle/code/java/security/TemplateInjection.qll b/java/ql/lib/semmle/code/java/security/TemplateInjection.qll index a74f4db8030a..0b703780a035 100644 --- a/java/ql/lib/semmle/code/java/security/TemplateInjection.qll +++ b/java/ql/lib/semmle/code/java/security/TemplateInjection.qll @@ -9,30 +9,12 @@ private import semmle.code.java.security.Sanitizers /** * A source for server-side template injection (SST) vulnerabilities. */ -abstract class TemplateInjectionSource extends DataFlow::Node { - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if this source has the specified `state`. - */ - deprecated predicate hasState(DataFlow::FlowState state) { - state instanceof DataFlow::FlowStateEmpty - } -} +abstract class TemplateInjectionSource extends DataFlow::Node { } /** * A sink for server-side template injection (SST) vulnerabilities. */ -abstract class TemplateInjectionSink extends DataFlow::Node { - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if this sink has the specified `state`. - */ - deprecated predicate hasState(DataFlow::FlowState state) { - state instanceof DataFlow::FlowStateEmpty - } -} +abstract class TemplateInjectionSink extends DataFlow::Node { } /** * A unit class for adding additional taint steps. @@ -46,20 +28,6 @@ class TemplateInjectionAdditionalTaintStep extends Unit { * step for flows related to server-side template injection (SST) vulnerabilities. */ predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if the step from `node1` to `node2` should be considered a taint - * step for flows related toserver-side template injection (SST) vulnerabilities. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - deprecated predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } } /** @@ -67,22 +35,6 @@ class TemplateInjectionAdditionalTaintStep extends Unit { */ abstract class TemplateInjectionSanitizer extends DataFlow::Node { } -/** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * A sanitizer for server-side template injection (SST) vulnerabilities. - * This sanitizer is only applicable when `TemplateInjectionSanitizerWithState::hasState` - * holds for the flow state. - */ -abstract deprecated class TemplateInjectionSanitizerWithState extends DataFlow::Node { - /** - * DEPRECATED: Open-ended flow state is not intended to be part of the extension points. - * - * Holds if this sanitizer has the specified `state`. - */ - abstract deprecated predicate hasState(DataFlow::FlowState state); -} - private class DefaultTemplateInjectionSource extends TemplateInjectionSource instanceof ActiveThreatModelSource { } diff --git a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll index 9a627d54c5ae..cb76ee37c7be 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll @@ -4,7 +4,6 @@ import semmle.code.java.dataflow.FlowSources private import semmle.code.java.dataflow.FlowSinks -private import semmle.code.java.dataflow.TaintTracking2 private import semmle.code.java.dispatch.VirtualDispatch private import semmle.code.java.frameworks.Kryo private import semmle.code.java.frameworks.XStream diff --git a/java/ql/lib/semmle/code/java/security/XmlParsers.qll b/java/ql/lib/semmle/code/java/security/XmlParsers.qll index 4a5b7121e603..fc0b52b6f789 100644 --- a/java/ql/lib/semmle/code/java/security/XmlParsers.qll +++ b/java/ql/lib/semmle/code/java/security/XmlParsers.qll @@ -2,8 +2,6 @@ import java import semmle.code.java.dataflow.DataFlow -deprecated import semmle.code.java.dataflow.DataFlow3 -private import semmle.code.java.dataflow.DataFlow3 private import semmle.code.java.dataflow.RangeUtils private module Frameworks { diff --git a/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll b/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll index 8e545a5e8f04..5972db674955 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll @@ -95,7 +95,7 @@ private class ProduceCiphertextCall extends ProduceCryptoCall { } /** Holds if `fromNode` to `toNode` is a dataflow step that updates a cryptographic operation. */ -private predicate updateCryptoOperationStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) { +private predicate updateCryptoOperationStep(DataFlow::Node fromNode, DataFlow::Node toNode) { exists(MethodCall call, Method m | m = call.getMethod() and call.getQualifier() = toNode.asExpr() and @@ -111,7 +111,7 @@ private predicate updateCryptoOperationStep(DataFlow2::Node fromNode, DataFlow2: } /** Holds if `fromNode` to `toNode` is a dataflow step that creates a hash. */ -private predicate createMessageDigestStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) { +private predicate createMessageDigestStep(DataFlow::Node fromNode, DataFlow::Node toNode) { exists(MethodCall ma, Method m | m = ma.getMethod() | m.getDeclaringType().hasQualifiedName("java.security", "MessageDigest") and m.hasStringSignature("digest()") and @@ -135,7 +135,7 @@ private predicate createMessageDigestStep(DataFlow2::Node fromNode, DataFlow2::N } /** Holds if `fromNode` to `toNode` is a dataflow step that updates a hash. */ -private predicate updateMessageDigestStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) { +private predicate updateMessageDigestStep(DataFlow::Node fromNode, DataFlow::Node toNode) { exists(MethodCall ma, Method m | m = ma.getMethod() | m.hasQualifiedName("java.security", "MessageDigest", "update") and ma.getArgument(0) = fromNode.asExpr() and @@ -154,7 +154,7 @@ private module UserInputInCryptoOperationConfig implements DataFlow::ConfigSig { exists(ProduceCryptoCall call | call.getQualifier() = sink.asExpr()) } - predicate isAdditionalFlowStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) { + predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { updateCryptoOperationStep(fromNode, toNode) or createMessageDigestStep(fromNode, toNode) diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll index 925fd5632a35..5f015732cb38 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll @@ -94,11 +94,11 @@ private class CompileRegexSink extends DataFlow::ExprNode { * A data flow configuration for regular expressions that include permissive dots. */ private module PermissiveDotRegexConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow2::Node src) { src.asExpr() instanceof PermissiveDotStr } + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof PermissiveDotStr } - predicate isSink(DataFlow2::Node sink) { sink instanceof CompileRegexSink } + predicate isSink(DataFlow::Node sink) { sink instanceof CompileRegexSink } - predicate isBarrier(DataFlow2::Node node) { + predicate isBarrier(DataFlow::Node node) { exists( MethodCall ma, Field f // Pattern.compile(PATTERN, Pattern.DOTALL) | diff --git a/java/ql/src/experimental/semmle/code/java/security/SpringUrlRedirect.qll b/java/ql/src/experimental/semmle/code/java/security/SpringUrlRedirect.qll index d437c8fa3cc0..c068dfbb7e36 100644 --- a/java/ql/src/experimental/semmle/code/java/security/SpringUrlRedirect.qll +++ b/java/ql/src/experimental/semmle/code/java/security/SpringUrlRedirect.qll @@ -53,7 +53,7 @@ private class SpringViewUrlRedirectSink extends SpringUrlRedirectSink { ) or exists(MethodCall ma, RedirectAppendCall rac | - DataFlow2::localExprFlow(rac.getQualifier(), ma.getQualifier()) and + DataFlow::localExprFlow(rac.getQualifier(), ma.getQualifier()) and ma.getMethod().hasName("append") and ma.getArgument(0) = this.asExpr() and any(SpringRequestMappingMethod sqmm).polyCalls*(this.getEnclosingCallable()) diff --git a/python/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/python/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 000000000000..d09ec528c99e --- /dev/null +++ b/python/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/python/ql/lib/semmle/python/dataflow/new/DataFlow.qll b/python/ql/lib/semmle/python/dataflow/new/DataFlow.qll index 17cc0a0ee858..670f42a8dc5f 100644 --- a/python/ql/lib/semmle/python/dataflow/new/DataFlow.qll +++ b/python/ql/lib/semmle/python/dataflow/new/DataFlow.qll @@ -25,5 +25,5 @@ module DataFlow { private import internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import internal.DataFlowImpl1 + import Public } diff --git a/python/ql/lib/semmle/python/dataflow/new/DataFlow2.qll b/python/ql/lib/semmle/python/dataflow/new/DataFlow2.qll deleted file mode 100644 index 753fe5530930..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/DataFlow2.qll +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Provides a library for local (intra-procedural) and global (inter-procedural) - * data flow analysis: deciding whether data can flow from a _source_ to a - * _sink_. - * - * Unless configured otherwise, _flow_ means that the exact value of - * the source may reach the sink. We do not track flow across pointer - * dereferences or array indexing. To track these types of flow, where the - * exact value may not be preserved, import - * `semmle.python.dataflow.new.TaintTracking`. - * - * To use global (interprocedural) data flow, extend the class - * `DataFlow::Configuration` as documented on that class. To use local - * (intraprocedural) data flow, call `DataFlow::localFlow` or - * `DataFlow::localFlowStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow2 { - import semmle.python.dataflow.new.internal.DataFlowImpl2 -} diff --git a/python/ql/lib/semmle/python/dataflow/new/DataFlow3.qll b/python/ql/lib/semmle/python/dataflow/new/DataFlow3.qll deleted file mode 100644 index c6b7304319bf..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/DataFlow3.qll +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Provides a library for local (intra-procedural) and global (inter-procedural) - * data flow analysis: deciding whether data can flow from a _source_ to a - * _sink_. - * - * Unless configured otherwise, _flow_ means that the exact value of - * the source may reach the sink. We do not track flow across pointer - * dereferences or array indexing. To track these types of flow, where the - * exact value may not be preserved, import - * `semmle.python.dataflow.new.TaintTracking`. - * - * To use global (interprocedural) data flow, extend the class - * `DataFlow::Configuration` as documented on that class. To use local - * (intraprocedural) data flow, call `DataFlow::localFlow` or - * `DataFlow::localFlowStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow3 { - import semmle.python.dataflow.new.internal.DataFlowImpl3 -} diff --git a/python/ql/lib/semmle/python/dataflow/new/DataFlow4.qll b/python/ql/lib/semmle/python/dataflow/new/DataFlow4.qll deleted file mode 100644 index 44d926a274de..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/DataFlow4.qll +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Provides a library for local (intra-procedural) and global (inter-procedural) - * data flow analysis: deciding whether data can flow from a _source_ to a - * _sink_. - * - * Unless configured otherwise, _flow_ means that the exact value of - * the source may reach the sink. We do not track flow across pointer - * dereferences or array indexing. To track these types of flow, where the - * exact value may not be preserved, import - * `semmle.python.dataflow.new.TaintTracking`. - * - * To use global (interprocedural) data flow, extend the class - * `DataFlow::Configuration` as documented on that class. To use local - * (intraprocedural) data flow, call `DataFlow::localFlow` or - * `DataFlow::localFlowStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow4 { - import semmle.python.dataflow.new.internal.DataFlowImpl4 -} diff --git a/python/ql/lib/semmle/python/dataflow/new/TaintTracking.qll b/python/ql/lib/semmle/python/dataflow/new/TaintTracking.qll index e085ba45dd00..01174d5e7a02 100644 --- a/python/ql/lib/semmle/python/dataflow/new/TaintTracking.qll +++ b/python/ql/lib/semmle/python/dataflow/new/TaintTracking.qll @@ -15,10 +15,9 @@ private import python * global (inter-procedural) taint-tracking analyses. */ module TaintTracking { - import semmle.python.dataflow.new.internal.tainttracking1.TaintTrackingParameter::Public + import semmle.python.dataflow.new.internal.TaintTrackingPublic private import semmle.python.dataflow.new.internal.DataFlowImplSpecific private import semmle.python.dataflow.new.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking import TaintFlowMake - import internal.tainttracking1.TaintTrackingImpl } diff --git a/python/ql/lib/semmle/python/dataflow/new/TaintTracking2.qll b/python/ql/lib/semmle/python/dataflow/new/TaintTracking2.qll deleted file mode 100644 index 5d78a531e2e1..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/TaintTracking2.qll +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - * - * To use global (interprocedural) taint tracking, extend the class - * `TaintTracking::Configuration` as documented on that class. To use local - * (intraprocedural) taint tracking, call `TaintTracking::localTaint` or - * `TaintTracking::localTaintStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking2 { - import semmle.python.dataflow.new.internal.tainttracking2.TaintTrackingImpl -} diff --git a/python/ql/lib/semmle/python/dataflow/new/TaintTracking3.qll b/python/ql/lib/semmle/python/dataflow/new/TaintTracking3.qll deleted file mode 100644 index d3173ec8f9fa..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/TaintTracking3.qll +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - * - * To use global (interprocedural) taint tracking, extend the class - * `TaintTracking::Configuration` as documented on that class. To use local - * (intraprocedural) taint tracking, call `TaintTracking::localTaint` or - * `TaintTracking::localTaintStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking3 { - import semmle.python.dataflow.new.internal.tainttracking3.TaintTrackingImpl -} diff --git a/python/ql/lib/semmle/python/dataflow/new/TaintTracking4.qll b/python/ql/lib/semmle/python/dataflow/new/TaintTracking4.qll deleted file mode 100644 index f452cf4ed00b..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/TaintTracking4.qll +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - * - * To use global (interprocedural) taint tracking, extend the class - * `TaintTracking::Configuration` as documented on that class. To use local - * (intraprocedural) taint tracking, call `TaintTracking::localTaint` or - * `TaintTracking::localTaintStep` with arguments of type `DataFlow::Node`. - */ - -private import python - -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) taint-tracking analyses. - */ -module TaintTracking4 { - import semmle.python.dataflow.new.internal.tainttracking4.TaintTrackingImpl -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingParameter.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index badbe01f4c58..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,7 +0,0 @@ -import semmle.python.dataflow.new.internal.TaintTrackingPublic as Public - -module Private { - import semmle.python.dataflow.new.DataFlow::DataFlow as DataFlow - import semmle.python.dataflow.new.internal.DataFlowImpl as DataFlowInternal - import semmle.python.dataflow.new.internal.TaintTrackingPrivate -} 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingParameter.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingParameter.qll deleted file mode 100644 index fa5201b6020a..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.python.dataflow.new.internal.TaintTrackingPublic as Public - -module Private { - import semmle.python.dataflow.new.DataFlow2::DataFlow2 as DataFlow - import semmle.python.dataflow.new.internal.TaintTrackingPrivate -} 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingParameter.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingParameter.qll deleted file mode 100644 index 390a1fd7ed0b..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.python.dataflow.new.internal.TaintTrackingPublic as Public - -module Private { - import semmle.python.dataflow.new.DataFlow3::DataFlow3 as DataFlow - import semmle.python.dataflow.new.internal.TaintTrackingPrivate -} 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 deleted file mode 100644 index 75e7856fd261..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingParameter.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingParameter.qll deleted file mode 100644 index 3072d32c1264..000000000000 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingParameter.qll +++ /dev/null @@ -1,6 +0,0 @@ -import semmle.python.dataflow.new.internal.TaintTrackingPublic as Public - -module Private { - import semmle.python.dataflow.new.DataFlow4::DataFlow4 as DataFlow - import semmle.python.dataflow.new.internal.TaintTrackingPrivate -} diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll index 0b0cb0468206..03b1db49d170 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingQuery.qll @@ -15,25 +15,6 @@ private import semmle.python.dataflow.new.BarrierGuards private import semmle.python.dataflow.new.SensitiveDataSources import CleartextLoggingCustomizations::CleartextLogging -/** - * DEPRECATED: Use `CleartextLoggingFlow` module instead. - * - * A taint-tracking configuration for detecting "Clear-text logging of sensitive information". - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CleartextLogging" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof Sanitizer - } -} - private module CleartextLoggingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll index ef9c8c13b56b..7ee85230c84f 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageQuery.qll @@ -15,25 +15,6 @@ private import semmle.python.dataflow.new.BarrierGuards private import semmle.python.dataflow.new.SensitiveDataSources import CleartextStorageCustomizations::CleartextStorage -/** - * DEPRECATED: Use `CleartextStorageFlow` module instead. - * - * A taint-tracking configuration for detecting "Clear-text storage of sensitive information". - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CleartextStorage" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof Sanitizer - } -} - private module CleartextStorageConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll index ecb0435fec82..486d06a6b21b 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CodeInjectionQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import CodeInjectionCustomizations::CodeInjection -/** - * DEPRECATED: Use `CodeInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "code injection" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CodeInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module CodeInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll index 8874a12132fe..18bcbe8cdd5e 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CommandInjectionQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import CommandInjectionCustomizations::CommandInjection -/** - * DEPRECATED: Use `CommandInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "command injection" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CommandInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - /** * A taint-tracking configuration for detecting "command injection" vulnerabilities. */ diff --git a/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll index 9dd24bceddb3..527c1cbfe432 100644 --- a/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/LdapInjectionQuery.qll @@ -13,22 +13,6 @@ import semmle.python.dataflow.new.TaintTracking import semmle.python.dataflow.new.RemoteFlowSources import LdapInjectionCustomizations::LdapInjection -/** - * DEPRECATED: Use `LdapInjectionDnFlow` module instead. - * - * A taint-tracking configuration for detecting LDAP injection vulnerabilities - * via the distinguished name (DN) parameter of an LDAP search. - */ -deprecated class DnConfiguration extends TaintTracking::Configuration { - DnConfiguration() { this = "LdapDnInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof DnSink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof DnSanitizer } -} - private module LdapInjectionDnConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -40,22 +24,6 @@ private module LdapInjectionDnConfig implements DataFlow::ConfigSig { /** Global taint-tracking for detecting "LDAP injection via the distinguished name (DN) parameter" vulnerabilities. */ module LdapInjectionDnFlow = TaintTracking::Global; -/** - * DEPRECATED: Use `LdapInjectionFilterFlow` module instead. - * - * A taint-tracking configuration for detecting LDAP injection vulnerabilities - * via the filter parameter of an LDAP search. - */ -deprecated class FilterConfiguration extends TaintTracking::Configuration { - FilterConfiguration() { this = "LdapFilterInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof FilterSink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof FilterSanitizer } -} - private module LdapInjectionFilterConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll index 780c27bb2131..7204accbdcf2 100644 --- a/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/LogInjectionQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import LogInjectionCustomizations::LogInjection -/** - * DEPRECATED: Use `LogInjectionFlow` module instead. - * - * A taint-tracking configuration for tracking untrusted user input used in log entries. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "LogInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module LogInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll b/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll index 4b150299b318..eb83d0bf84f0 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll @@ -11,35 +11,6 @@ import semmle.python.ApiGraphs import semmle.python.dataflow.new.TaintTracking import PamAuthorizationCustomizations::PamAuthorizationCustomizations -/** - * DEPRECATED: Use `PamAuthorizationFlow` module instead. - * - * A taint-tracking configuration for detecting "PAM Authorization" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "PamAuthorization" } - - override predicate isSource(DataFlow::Node node) { node instanceof Source } - - override predicate isSink(DataFlow::Node node) { node instanceof Sink } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - // Models flow from a remotely supplied username field to a PAM `handle`. - // `retval = pam_start(service, username, byref(conv), byref(handle))` - exists(API::CallNode pamStart, DataFlow::Node handle, API::CallNode pointer | - pointer = API::moduleImport("ctypes").getMember(["pointer", "byref"]).getACall() and - pamStart = libPam().getMember("pam_start").getACall() and - pointer = pamStart.getArg(3) and - handle = pointer.getArg(0) and - pamStart.getArg(1) = node1 and - handle = node2 - ) - or - // Flow from handle to the authenticate call in the final step - exists(VulnPamAuthCall c | c.getArg(0) = node1 | node2 = c) - } -} - private module PamAuthorizationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll index 2cd6ba2a6f40..b3081fd9996a 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll @@ -12,57 +12,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import PathInjectionCustomizations::PathInjection -/** - * DEPRECATED: Use `PathInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "path injection" vulnerabilities. - * - * This configuration uses two flow states, `NotNormalized` and `NormalizedUnchecked`, - * to track the requirement that a file path must be first normalized and then checked - * before it is safe to use. - * - * At sources, paths are assumed not normalized. At normalization points, they change - * state to `NormalizedUnchecked` after which they can be made safe by an appropriate - * check of the prefix. - * - * Such checks are ineffective in the `NotNormalized` state. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "PathInjection" } - - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - source instanceof Source and state instanceof NotNormalized - } - - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - sink instanceof Sink and - ( - state instanceof NotNormalized or - state instanceof NormalizedUnchecked - ) - } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - override predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { - // Block `NotNormalized` paths here, since they change state to `NormalizedUnchecked` - node instanceof Path::PathNormalization and - state instanceof NotNormalized - or - node instanceof Path::SafeAccessCheck and - state instanceof NormalizedUnchecked - } - - override predicate isAdditionalTaintStep( - DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo, - DataFlow::FlowState stateTo - ) { - nodeFrom = nodeTo.(Path::PathNormalization).getPathArg() and - stateFrom instanceof NotNormalized and - stateTo instanceof NormalizedUnchecked - } -} - abstract private class NormalizationState extends string { bindingset[this] NormalizationState() { any() } diff --git a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll b/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll index 3ca67fff82e5..4e082aac26e4 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoSQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import PolynomialReDoSCustomizations::PolynomialReDoS -/** - * DEPRECATED: Use `PolynomialReDoSFlow` module instead. - * - * A taint-tracking configuration for detecting "polynomial regular expression denial of service (ReDoS)" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "PolynomialReDoS" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module PolynomialReDoSConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll b/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll index d67c5e3cb39f..5f5b2dd58df5 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ReflectedXssQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import ReflectedXSSCustomizations::ReflectedXss -/** - * DEPRECATED: Use `ReflectedXssFlow` module instead. - * - * A taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ReflectedXSS" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module ReflectedXssConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll index d79b76a8685c..ae21270a63ea 100644 --- a/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/RegexInjectionQuery.qll @@ -12,21 +12,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import RegexInjectionCustomizations::RegexInjection -/** - * DEPRECATED: Use `RegexInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "RegexInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module RegexInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll index d0bfa24cf5e9..4cae5a301b1f 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll @@ -12,31 +12,6 @@ import semmle.python.dataflow.new.TaintTracking import semmle.python.Concepts import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery -/** - * DEPRECATED: Use `FullServerSideRequestForgeryFlow` module instead. - * - * A taint-tracking configuration for detecting "Server-side request forgery" vulnerabilities. - * - * This configuration has a sanitizer to limit results to cases where attacker has full control of URL. - * See `PartialServerSideRequestForgery` for a variant without this requirement. - * - * You should use the `fullyControlledRequest` to only select results where all - * URL parts are fully controlled. - */ -deprecated class FullServerSideRequestForgeryConfiguration extends TaintTracking::Configuration { - FullServerSideRequestForgeryConfiguration() { this = "FullServerSideRequestForgery" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Sanitizer - or - node instanceof FullUrlControlSanitizer - } -} - /** * This configuration has a sanitizer to limit results to cases where attacker has full control of URL. * See `PartialServerSideRequestForgery` for a variant without this requirement. @@ -73,24 +48,6 @@ predicate fullyControlledRequest(Http::Client::Request request) { ) } -/** - * DEPRECATED: Use `PartialServerSideRequestForgeryFlow` module instead. - * - * A taint-tracking configuration for detecting "Server-side request forgery" vulnerabilities. - * - * This configuration has results, even when the attacker does not have full control over the URL. - * See `FullServerSideRequestForgeryConfiguration`, and the `fullyControlledRequest` predicate. - */ -deprecated class PartialServerSideRequestForgeryConfiguration extends TaintTracking::Configuration { - PartialServerSideRequestForgeryConfiguration() { this = "PartialServerSideRequestForgery" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - /** * This configuration has results, even when the attacker does not have full control over the URL. * See `FullServerSideRequestForgeryConfiguration`, and the `fullyControlledRequest` predicate. diff --git a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll index 877e30f50903..a63590643f3a 100644 --- a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import SqlInjectionCustomizations::SqlInjection -/** - * DEPRECATED: Use `SqlInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "SQL injection" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SqlInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module SqlInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll b/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll index 9980aa76ea37..57ef6d7ebb2a 100644 --- a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureQuery.qll @@ -11,30 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import StackTraceExposureCustomizations::StackTraceExposure -/** - * DEPRECATED: Use `StackTraceExposureFlow` module instead. - * - * A taint-tracking configuration for detecting "stack trace exposure" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "StackTraceExposure" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - // A stack trace is accessible as the `__traceback__` attribute of a caught exception. - // see https://docs.python.org/3/reference/datamodel.html#traceback-objects - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - exists(DataFlow::AttrRead attr | attr.getAttributeName() = "__traceback__" | - nodeFrom = attr.getObject() and - nodeTo = attr - ) - } -} - private module StackTraceExposureConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll index 7bb008f1afb3..162bfcd74ccb 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import TarSlipCustomizations::TarSlip -/** - * DEPRECATED: Use `TarSlipFlow` module instead. - * - * A taint-tracking configuration for detecting "tar slip" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "TarSlip" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module TarSlipConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll index bd067213fb5d..dd6925b79983 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import UnsafeDeserializationCustomizations::UnsafeDeserialization -/** - * DEPRECATED: Use `UnsafeDeserializationFlow` module instead. - * - * A taint-tracking configuration for detecting "code execution from deserialization" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeDeserialization" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module UnsafeDeserializationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll index 6d292a88b6c7..51341cfe6cdc 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll @@ -13,29 +13,6 @@ private import semmle.python.dataflow.new.TaintTracking private import CommandInjectionCustomizations::CommandInjection as CommandInjection private import semmle.python.dataflow.new.BarrierGuards -/** - * DEPRECATED: Use `UnsafeShellCommandConstructionFlow` module instead. - * - * A taint-tracking configuration for detecting shell command constructed from library input vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeShellCommandConstruction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Sanitizer or - node instanceof CommandInjection::Sanitizer // using all sanitizers from `py/command-injection` - } - - // override to require the path doesn't have unmatched return steps - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSourceCallContext - } -} - /** * A taint-tracking configuration for detecting "shell command constructed from library input" vulnerabilities. */ diff --git a/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll index 5b44cd988ad1..a9526f33ad34 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UrlRedirectQuery.qll @@ -11,34 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import UrlRedirectCustomizations::UrlRedirect as UrlRedirect -/** - * DEPRECATED: Use `UrlRedirectFlow` module instead. - * - * A taint-tracking configuration for detecting "URL redirection" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UrlRedirect" } - - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - source instanceof UrlRedirect::Source and state instanceof UrlRedirect::MayContainBackslashes - } - - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - sink instanceof UrlRedirect::Sink and state instanceof UrlRedirect::FlowState - } - - override predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { - node.(UrlRedirect::Sanitizer).sanitizes(state) - } - - override predicate isAdditionalTaintStep( - DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo, - DataFlow::FlowState stateTo - ) { - any(UrlRedirect::AdditionalFlowStep a).step(nodeFrom, stateFrom, nodeTo, stateTo) - } -} - private module UrlRedirectConfig implements DataFlow::StateConfigSig { class FlowState = UrlRedirect::FlowState; diff --git a/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll b/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll index 9e2803b33699..04d8846d7d01 100644 --- a/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashingQuery.qll @@ -23,30 +23,6 @@ private import semmle.python.dataflow.new.SensitiveDataSources module NormalHashFunction { import WeakSensitiveDataHashingCustomizations::NormalHashFunction - /** - * DEPRECATED: Use `Flow` module instead. - * - * A taint-tracking configuration for detecting use of a broken or weak - * cryptographic hashing algorithm on sensitive data. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "NormalHashFunction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof Sanitizer - } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - sensitiveDataExtraStepForCalls(node1, node2) - } - } - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -73,33 +49,6 @@ module NormalHashFunction { module ComputationallyExpensiveHashFunction { import WeakSensitiveDataHashingCustomizations::ComputationallyExpensiveHashFunction - /** - * DEPRECATED: Use `Flow` module instead. - * - * A taint-tracking configuration for detecting use of a broken or weak - * cryptographic hashing algorithm on passwords. - * - * Passwords has stricter requirements on the hashing algorithm used (must be - * computationally expensive to prevent brute-force attacks). - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ComputationallyExpensiveHashFunction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof Sanitizer - } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - sensitiveDataExtraStepForCalls(node1, node2) - } - } - /** * Passwords has stricter requirements on the hashing algorithm used (must be * computationally expensive to prevent brute-force attacks). diff --git a/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll b/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll index dcf3939bc786..e69e8ad63c68 100644 --- a/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/XmlBombQuery.qll @@ -11,24 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import XmlBombCustomizations::XmlBomb -/** - * DEPRECATED: Use `XmlBombFlow` module instead. - * - * A taint-tracking configuration for detecting "XML bomb" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "XmlBomb" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } -} - private module XmlBombConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll index f8a21aedba59..2a15669f6ff0 100644 --- a/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/XpathInjectionQuery.qll @@ -11,21 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import XpathInjectionCustomizations::XpathInjection -/** - * DEPRECATED: Use `XpathInjectionFlow` module instead. - * - * A taint-tracking configuration for detecting "Xpath Injection" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "Xpath Injection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module XpathInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll b/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll index 8d85d275f1e1..da7c34a5bac3 100644 --- a/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/XxeQuery.qll @@ -11,24 +11,6 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import XxeCustomizations::Xxe -/** - * DEPRECATED: Use `XxeFlow` module instead. - * - * A taint-tracking configuration for detecting "XML External Entity (XXE)" vulnerabilities. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "Xxe" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } -} - private module XxeConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll b/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll index a65569510dff..d2b47c9a6a76 100644 --- a/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll +++ b/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll @@ -167,19 +167,6 @@ class ExternalApiDataNode extends DataFlow::Node { } } -/** - * DEPRECATED: Use `XmlBombFlow` module instead. - * - * A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. - */ -deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { - UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" } - - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } -} - private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } diff --git a/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll index 68194309e1dd..290087f6a71c 100644 --- a/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll +++ b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll @@ -16,37 +16,6 @@ private import semmle.python.ApiGraphs module ModificationOfParameterWithDefault { import ModificationOfParameterWithDefaultCustomizations::ModificationOfParameterWithDefault - /** - * DEPRECATED: Use `Flow` module instead. - * - * A data-flow configuration for detecting modifications of a parameters default value. - */ - deprecated class Configuration extends DataFlow::Configuration { - /** Record whether the default value being tracked is non-empty. */ - boolean nonEmptyDefault; - - Configuration() { - nonEmptyDefault in [true, false] and - this = "ModificationOfParameterWithDefault:" + nonEmptyDefault.toString() - } - - override predicate isSource(DataFlow::Node source) { - source.(Source).isNonEmpty() = nonEmptyDefault - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isBarrier(DataFlow::Node node) { - // if we are tracking a non-empty default, then it is ok to modify empty values, - // so our tracking ends at those. - nonEmptyDefault = true and node instanceof MustBeEmpty - or - // if we are tracking a empty default, then it is ok to modify non-empty values, - // so our tracking ends at those. - nonEmptyDefault = false and node instanceof MustBeNonEmpty - } - } - private module Config implements DataFlow::StateConfigSig { class FlowState = boolean; diff --git a/python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll b/python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll index 19af6cbf807e..e9f13aaaa475 100644 --- a/python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll +++ b/python/ql/test/TestUtilities/dataflow/DataflowQueryTest.qll @@ -103,15 +103,3 @@ module FromTaintTrackingStateConfig { import MakeQueryTest } - -deprecated signature class LegacyConfiguration extends DataFlow::Configuration; - -deprecated module FromLegacyConfiguration { - module Impl implements QueryTestSig { - predicate isSink(DataFlow::Node sink) { any(C c).isSink(sink) or any(C c).isSink(sink, _) } - - predicate flowTo(DataFlow::Node sink) { any(C c).hasFlowTo(sink) } - } - - import MakeQueryTest -} diff --git a/ruby/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/ruby/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 000000000000..d09ec528c99e --- /dev/null +++ b/ruby/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/ruby/ql/lib/codeql/ruby/DataFlow.qll b/ruby/ql/lib/codeql/ruby/DataFlow.qll index f17c85143f5d..72fb8c880ec9 100644 --- a/ruby/ql/lib/codeql/ruby/DataFlow.qll +++ b/ruby/ql/lib/codeql/ruby/DataFlow.qll @@ -13,5 +13,5 @@ module DataFlow { private import codeql.ruby.dataflow.internal.DataFlowImplSpecific private import codeql.dataflow.DataFlow import DataFlowMake - import codeql.ruby.dataflow.internal.DataFlowImpl1 + import Public } diff --git a/ruby/ql/lib/codeql/ruby/DataFlow2.qll b/ruby/ql/lib/codeql/ruby/DataFlow2.qll deleted file mode 100644 index 7486f52052d5..000000000000 --- a/ruby/ql/lib/codeql/ruby/DataFlow2.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Provides classes for performing local (intra-procedural) and - * global (inter-procedural) data flow analyses. - */ -module DataFlow2 { - import codeql.ruby.dataflow.internal.DataFlowImpl2 -} diff --git a/ruby/ql/lib/codeql/ruby/TaintTracking.qll b/ruby/ql/lib/codeql/ruby/TaintTracking.qll index 7534b28079ae..45828c86dd23 100644 --- a/ruby/ql/lib/codeql/ruby/TaintTracking.qll +++ b/ruby/ql/lib/codeql/ruby/TaintTracking.qll @@ -3,11 +3,10 @@ * global (inter-procedural) taint-tracking analyses. */ module TaintTracking { - import codeql.ruby.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import codeql.ruby.dataflow.internal.TaintTrackingPublic private import codeql.ruby.dataflow.internal.DataFlowImplSpecific private import codeql.ruby.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking private import codeql.Locations import TaintFlowMake - import codeql.ruby.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd261..000000000000 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index 0c87c8ac5e83..000000000000 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,7 +0,0 @@ -import codeql.ruby.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import codeql.ruby.DataFlow::DataFlow as DataFlow - import codeql.ruby.dataflow.internal.DataFlowImpl as DataFlowInternal - import codeql.ruby.dataflow.internal.TaintTrackingPrivate -} diff --git a/ruby/ql/lib/codeql/ruby/experimental/UnicodeBypassValidationQuery.qll b/ruby/ql/lib/codeql/ruby/experimental/UnicodeBypassValidationQuery.qll index 26011c8d918d..7a5be05ac303 100644 --- a/ruby/ql/lib/codeql/ruby/experimental/UnicodeBypassValidationQuery.qll +++ b/ruby/ql/lib/codeql/ruby/experimental/UnicodeBypassValidationQuery.qll @@ -9,22 +9,6 @@ private import codeql.ruby.TaintTracking private import codeql.ruby.ApiGraphs import UnicodeBypassValidationCustomizations::UnicodeBypassValidation -/** - * A state signifying that a logical validation has not been performed. - * DEPRECATED: Use `PreValidationState()` - */ -deprecated class PreValidation extends DataFlow::FlowState { - PreValidation() { this = "PreValidation" } -} - -/** - * A state signifying that a logical validation has been performed. - * DEPRECATED: Use `PostValidationState()` - */ -deprecated class PostValidation extends DataFlow::FlowState { - PostValidation() { this = "PostValidation" } -} - /** * A state signifying if a logical validation has been performed or not. */ @@ -34,40 +18,6 @@ private newtype ValidationState = // A state signifying that a logical validation has been performed. PostValidationState() -/** - * A taint-tracking configuration for detecting "Unicode transformation mishandling" vulnerabilities. - * - * This configuration uses two flow states, `PreValidation` and `PostValidation`, - * to track the requirement that a logical validation has been performed before the Unicode Transformation. - * DEPRECATED: Use `UnicodeBypassValidationFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnicodeBypassValidation" } - - private ValidationState convertState(DataFlow::FlowState state) { - state instanceof PreValidation and result = PreValidationState() - or - state instanceof PostValidation and result = PostValidationState() - } - - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - UnicodeBypassValidationConfig::isSource(source, this.convertState(state)) - } - - override predicate isAdditionalTaintStep( - DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo, - DataFlow::FlowState stateTo - ) { - UnicodeBypassValidationConfig::isAdditionalFlowStep(nodeFrom, this.convertState(stateFrom), - nodeTo, this.convertState(stateTo)) - } - - /* A Unicode Tranformation (Unicode tranformation) is considered a sink when the algorithm used is either NFC or NFKC. */ - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - UnicodeBypassValidationConfig::isSink(sink, this.convertState(state)) - } -} - /** * A taint-tracking configuration for detecting "Unicode transformation mishandling" vulnerabilities. * diff --git a/ruby/ql/lib/codeql/ruby/experimental/ZipSlipQuery.qll b/ruby/ql/lib/codeql/ruby/experimental/ZipSlipQuery.qll index f1a00b21d92b..cb6dfc931bd4 100644 --- a/ruby/ql/lib/codeql/ruby/experimental/ZipSlipQuery.qll +++ b/ruby/ql/lib/codeql/ruby/experimental/ZipSlipQuery.qll @@ -9,35 +9,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking private import codeql.ruby.ApiGraphs -/** - * A taint-tracking configuration for reasoning about zip slip - * vulnerabilities. - * DEPRECATED: Use `ZipSlipFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ZipSlip" } - - override predicate isSource(DataFlow::Node source) { source instanceof ZipSlip::Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof ZipSlip::Sink } - - /** - * This should actually be - * `and cn = API::getTopLevelMember("Gem").getMember("Package").getMember("TarReader").getMember("Entry").getAMethodCall("full_name")` and similar for other classes - * but I couldn't make it work so there's only check for the method name called on the entry. It is `full_name` for `Gem::Package::TarReader::Entry` and `Zlib` - * and `name` for `Zip::File` - */ - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - exists(DataFlow::CallNode cn | - cn.getReceiver() = nodeFrom and - cn.getMethodName() in ["full_name", "name"] and - cn = nodeTo - ) - } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof ZipSlip::Sanitizer } -} - private module ZipSlipConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ZipSlip::Source } diff --git a/ruby/ql/lib/codeql/ruby/security/CleartextLoggingQuery.qll b/ruby/ql/lib/codeql/ruby/security/CleartextLoggingQuery.qll index 2f321939ec20..38dc08731f42 100644 --- a/ruby/ql/lib/codeql/ruby/security/CleartextLoggingQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/CleartextLoggingQuery.qll @@ -12,28 +12,6 @@ private import codeql.ruby.TaintTracking import CleartextLoggingCustomizations::CleartextLogging private import CleartextLoggingCustomizations::CleartextLogging as CL -/** - * A taint-tracking configuration for detecting "Clear-text logging of sensitive information". - * DEPRECATED: Use `CleartextLoggingFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CleartextLogging" } - - override predicate isSource(DataFlow::Node source) { source instanceof CL::Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof CL::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof CL::Sanitizer - } - - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - CL::isAdditionalTaintStep(nodeFrom, nodeTo) - } -} - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof CL::Source } diff --git a/ruby/ql/lib/codeql/ruby/security/CleartextStorageQuery.qll b/ruby/ql/lib/codeql/ruby/security/CleartextStorageQuery.qll index 2a1a45bfb0b9..60dfd216609c 100644 --- a/ruby/ql/lib/codeql/ruby/security/CleartextStorageQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/CleartextStorageQuery.qll @@ -11,28 +11,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking private import CleartextStorageCustomizations::CleartextStorage as CS -/** - * A taint-tracking configuration for detecting "Clear-text storage of sensitive information". - * DEPRECATED: Use `CleartextStorageFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CleartextStorage" } - - override predicate isSource(DataFlow::Node source) { source instanceof CS::Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof CS::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) - or - node instanceof CS::Sanitizer - } - - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - CS::isAdditionalTaintStep(nodeFrom, nodeTo) - } -} - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof CS::Source } diff --git a/ruby/ql/lib/codeql/ruby/security/CodeInjectionCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/CodeInjectionCustomizations.qll index 8103ddf0c644..fe08d83d6fb0 100644 --- a/ruby/ql/lib/codeql/ruby/security/CodeInjectionCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/CodeInjectionCustomizations.qll @@ -14,18 +14,6 @@ private import codeql.ruby.frameworks.data.internal.ApiGraphModels module CodeInjection { /** Flow states used to distinguish whether an attacker controls the entire string. */ module FlowState { - /** - * Flow state used for normal tainted data, where an attacker might only control a substring. - * DEPRECATED: Use `SubString()` - */ - deprecated DataFlow::FlowState substring() { result = "substring" } - - /** - * Flow state used for data that is entirely controlled by the attacker. - * DEPRECATED: Use `Full()` - */ - deprecated DataFlow::FlowState full() { result = "full" } - private newtype TState = TFull() or TSubString() @@ -62,14 +50,6 @@ module CodeInjection { * A data flow source for "Code injection" vulnerabilities. */ abstract class Source extends DataFlow::Node { - /** - * Gets a flow state for which this is a source. - * DEPRECATED: Use `getAState()` - */ - deprecated DataFlow::FlowState getAFlowState() { - result = [FlowState::substring(), FlowState::full()] - } - /** Gets a flow state for which this is a source. */ FlowState::State getAState() { result instanceof FlowState::SubString or result instanceof FlowState::Full @@ -80,14 +60,6 @@ module CodeInjection { * A data flow sink for "Code injection" vulnerabilities. */ abstract class Sink extends DataFlow::Node { - /** - * Holds if this sink is safe for an attacker that only controls a substring. - * DEPRECATED: Use `getAState()` - */ - deprecated DataFlow::FlowState getAFlowState() { - result = [FlowState::substring(), FlowState::full()] - } - /** Holds if this sink is safe for an attacker that only controls a substring. */ FlowState::State getAState() { any() } } @@ -96,13 +68,6 @@ module CodeInjection { * A sanitizer for "Code injection" vulnerabilities. */ abstract class Sanitizer extends DataFlow::Node { - /** - * Gets a flow state for which this is a sanitizer. - * Sanitizes all states if the result is empty. - * DEPRECATED: Use `getAState()` - */ - deprecated DataFlow::FlowState getAFlowState() { none() } - /** * Gets a flow state for which this is a sanitizer. * Sanitizes all states if the result is empty. @@ -123,12 +88,6 @@ module CodeInjection { CodeExecutionAsSink() { this = c.getCode() } - deprecated override DataFlow::FlowState getAFlowState() { - if c.runsArbitraryCode() - then result = [FlowState::substring(), FlowState::full()] // If it runs arbitrary code then it's always vulnerable. - else result = FlowState::full() // If it "just" loads something, then it's only vulnerable if the attacker controls the entire string. - } - override FlowState::State getAState() { if c.runsArbitraryCode() then any() // If it runs arbitrary code then it's always vulnerable. @@ -153,8 +112,6 @@ module CodeInjection { ) } - deprecated override DataFlow::FlowState getAFlowState() { result = FlowState::full() } - override FlowState::State getAState() { result instanceof FlowState::Full } } diff --git a/ruby/ql/lib/codeql/ruby/security/CodeInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/CodeInjectionQuery.qll index 6641bbe2c340..9394601c5ed8 100644 --- a/ruby/ql/lib/codeql/ruby/security/CodeInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/CodeInjectionQuery.qll @@ -11,34 +11,6 @@ import codeql.ruby.TaintTracking import CodeInjectionCustomizations::CodeInjection import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting "Code injection" vulnerabilities. - * DEPRECATED: Use `CodeInjectionFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CodeInjection" } - - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - state = source.(Source).getAFlowState() - } - - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - state = sink.(Sink).getAFlowState() - } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Sanitizer and not exists(node.(Sanitizer).getAFlowState()) - or - node instanceof StringConstCompareBarrier - or - node instanceof StringConstArrayInclusionCallBarrier - } - - override predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { - node.(Sanitizer).getAFlowState() = state - } -} - private module Config implements DataFlow::StateConfigSig { class FlowState = FlowState::State; diff --git a/ruby/ql/lib/codeql/ruby/security/CommandInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/CommandInjectionQuery.qll index 4111d6c5d4af..74d00b254790 100644 --- a/ruby/ql/lib/codeql/ruby/security/CommandInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/CommandInjectionQuery.qll @@ -13,24 +13,6 @@ import CommandInjectionCustomizations::CommandInjection import codeql.ruby.DataFlow import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for reasoning about command-injection vulnerabilities. - * DEPRECATED: Use `CommandInjectionFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "CommandInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Sanitizer or - node instanceof StringConstCompareBarrier or - node instanceof StringConstArrayInclusionCallBarrier - } -} - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/ConditionalBypassQuery.qll b/ruby/ql/lib/codeql/ruby/security/ConditionalBypassQuery.qll index 2c4d3ede0f51..fa7e829d684f 100644 --- a/ruby/ql/lib/codeql/ruby/security/ConditionalBypassQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/ConditionalBypassQuery.qll @@ -11,23 +11,6 @@ private import codeql.ruby.TaintTracking private import codeql.ruby.security.SensitiveActions import ConditionalBypassCustomizations::ConditionalBypass -/** - * A taint tracking configuration for bypass of sensitive action guards. - * DEPRECATED: Use `ConditionalBypassFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ConditionalBypass" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } -} - private module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll index daba69f6ca2e..6d4d411baa12 100644 --- a/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll @@ -19,18 +19,6 @@ module HardcodedDataInterpretedAsCode { * Flow states used to distinguish value-preserving flow from taint flow. */ module FlowState { - /** - * Flow state used to track value-preserving flow. - * DEPRECATED: Use `Data()` - */ - deprecated DataFlow::FlowState data() { result = "data" } - - /** - * Flow state used to tainted data (non-value preserving flow). - * DEPRECATED: Use `Taint()` - */ - deprecated DataFlow::FlowState taint() { result = "taint" } - /** * Flow states used to distinguish value-preserving flow from taint flow. */ @@ -45,12 +33,6 @@ module HardcodedDataInterpretedAsCode { * A data flow source for hard-coded data. */ abstract class Source extends DataFlow::Node { - /** - * Gets a flow label for which this is a source. - * DEPRECATED: Use `getALabel()` - */ - deprecated DataFlow::FlowState getLabel() { result = FlowState::data() } - /** * Gets a flow label for which this is a source. */ @@ -64,17 +46,6 @@ module HardcodedDataInterpretedAsCode { /** Gets a description of what kind of sink this is. */ abstract string getKind(); - /** - * Gets a flow label for which this is a sink. - * DEPRECATED: Use `getALabel()` - */ - deprecated DataFlow::FlowState getLabel() { - // We want to ignore value-flow and only consider taint-flow, since the - // source is just a hex string, and evaluating that directly will just - // cause a syntax error. - result = FlowState::taint() - } - /** * Gets a flow label for which this is a sink. */ diff --git a/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll index a3e58f43e43a..3fdd6ffc2a4f 100644 --- a/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll @@ -12,39 +12,6 @@ private import codeql.ruby.TaintTracking private import codeql.ruby.dataflow.internal.TaintTrackingPrivate import HardcodedDataInterpretedAsCodeCustomizations::HardcodedDataInterpretedAsCode -/** - * A taint-tracking configuration for reasoning about hard-coded data - * being interpreted as code. - * - * DEPRECATED: Use `HardcodedDataInterpretedAsCodeFlow` instead - */ -deprecated class Configuration extends DataFlow::Configuration { - Configuration() { this = "HardcodedDataInterpretedAsCode" } - - override predicate isSource(DataFlow::Node source, DataFlow::FlowState label) { - source.(Source).getLabel() = label - } - - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState label) { - sink.(Sink).getLabel() = label - } - - override predicate isBarrier(DataFlow::Node node) { - super.isBarrier(node) or - node instanceof Sanitizer - } - - override predicate isAdditionalFlowStep( - DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo, - DataFlow::FlowState stateTo - ) { - defaultAdditionalTaintStep(nodeFrom, nodeTo, _) and - // This is a taint step, so the flow state becomes `taint`. - stateFrom = [FlowState::data(), FlowState::taint()] and - stateTo = FlowState::taint() - } -} - private module Config implements DataFlow::StateConfigSig { class FlowState = FlowState::State; diff --git a/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessQuery.qll b/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessQuery.qll index 9b3d7635c870..6a2eb63198ab 100644 --- a/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessQuery.qll @@ -23,19 +23,3 @@ module HttpToFileAccessConfig implements DataFlow::ConfigSig { * Taint tracking for writing user-controlled data to files. */ module HttpToFileAccessFlow = TaintTracking::Global; - -/** - * DEPRECATED. Use the `HttpToFileAccessFlow` module instead. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "HttpToFileAccess" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } -} diff --git a/ruby/ql/lib/codeql/ruby/security/ImproperLdapAuthQuery.qll b/ruby/ql/lib/codeql/ruby/security/ImproperLdapAuthQuery.qll index 81a85f596c93..bddc6d2c3c45 100644 --- a/ruby/ql/lib/codeql/ruby/security/ImproperLdapAuthQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/ImproperLdapAuthQuery.qll @@ -7,20 +7,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking private import ImproperLdapAuthCustomizations::ImproperLdapAuth -/** - * A taint-tracking configuration for detecting improper LDAP authentication vulnerabilities. - * DEPRECATED: Use `ImproperLdapAuthFlow` instead - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ImproperLdapAuth" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module ImproperLdapAuthConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll index 0ac51d38ed69..59fb2391c7e2 100644 --- a/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll @@ -19,12 +19,6 @@ module InsecureDownload { * A data flow source for download of sensitive file through insecure connection. */ abstract class Source extends DataFlow::Node { - /** - * Gets a flow-label for this source. - * DEPRECATED: Use `getAFlowLabel()` - */ - abstract deprecated DataFlow::FlowState getALabel(); - /** * Gets a flow-label for this source. */ @@ -40,12 +34,6 @@ module InsecureDownload { */ abstract DataFlow::Node getDownloadCall(); - /** - * Gets a flow-label where this sink is vulnerable. - * DEPRECATED: Use `getAFlowLabel()` - */ - abstract deprecated DataFlow::FlowState getALabel(); - /** * Gets a flow-label where this sink is vulnerable. */ @@ -61,30 +49,6 @@ module InsecureDownload { * Flow-labels for reasoning about download of sensitive file through insecure connection. */ module Label { - /** - * A flow-label for a URL that is downloaded over an insecure connection. - * DEPRECATED: Use `InsecureState()` - */ - deprecated class Insecure extends DataFlow::FlowState { - Insecure() { this = "insecure" } - } - - /** - * A flow-label for a URL that is sensitive. - * DEPRECATED: Use `SensitiveState()` - */ - deprecated class Sensitive extends DataFlow::FlowState { - Sensitive() { this = "sensitive" } - } - - /** - * A flow-label for file URLs that are both sensitive and downloaded over an insecure connection. - * DEPRECATED: Use `SensitiveInsecureState()` - */ - deprecated class SensitiveInsecure extends DataFlow::FlowState { - SensitiveInsecure() { this = "sensitiveInsecure" } - } - /** * Flow-labels for reasoning about download of sensitive file through insecure connection. */ @@ -114,13 +78,6 @@ module InsecureDownload { * seen as a source for downloads of sensitive files through an insecure connection. */ class InsecureFileUrl extends Source, InsecureUrl { - deprecated override DataFlow::FlowState getALabel() { - result instanceof Label::Insecure - or - hasUnsafeExtension(str) and - result instanceof Label::SensitiveInsecure - } - override Label::State getAFlowLabel() { result = Label::InsecureState() or @@ -136,8 +93,6 @@ module InsecureDownload { class SensitiveFileName extends Source { SensitiveFileName() { hasUnsafeExtension(this.asExpr().getConstantValue().getString()) } - deprecated override DataFlow::FlowState getALabel() { result instanceof Label::Sensitive } - override Label::State getAFlowLabel() { result = Label::SensitiveState() } } @@ -180,12 +135,6 @@ module InsecureDownload { override DataFlow::Node getDownloadCall() { result = req } - deprecated override DataFlow::FlowState getALabel() { - result instanceof Label::SensitiveInsecure - or - any(req.getAUrlPart()) instanceof InsecureUrl and result instanceof Label::Sensitive - } - override Label::State getAFlowLabel() { result = Label::SensitiveInsecureState() or @@ -232,8 +181,6 @@ module InsecureDownload { ) } - deprecated override DataFlow::FlowState getALabel() { result instanceof Label::Insecure } - override Label::State getAFlowLabel() { result = Label::InsecureState() } override DataFlow::Node getDownloadCall() { result = request } diff --git a/ruby/ql/lib/codeql/ruby/security/LogInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/LogInjectionQuery.qll index a2fce6ae06ba..648f9496ea19 100644 --- a/ruby/ql/lib/codeql/ruby/security/LogInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/LogInjectionQuery.qll @@ -25,20 +25,6 @@ abstract class Sink extends DataFlow::Node { } */ abstract class Sanitizer extends DataFlow::Node { } -/** - * A taint-tracking configuration for untrusted user input used in log entries. - * DEPRECATED: Use `LogInjectionFlow` - */ -deprecated class LogInjectionConfiguration extends TaintTracking::Configuration { - LogInjectionConfiguration() { this = "LogInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - /** * A source of remote user controlled input. */ diff --git a/ruby/ql/lib/codeql/ruby/security/PathInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/PathInjectionQuery.qll index 1c48d54e4241..55329c50717d 100644 --- a/ruby/ql/lib/codeql/ruby/security/PathInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/PathInjectionQuery.qll @@ -12,23 +12,6 @@ private import codeql.ruby.Concepts private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking -/** - * A taint-tracking configuration for reasoning about path injection - * vulnerabilities. - * DEPRECATED: Use `PathInjectionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "PathInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof PathInjection::Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof PathInjection::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Path::PathSanitization or node instanceof PathInjection::Sanitizer - } -} - private module PathInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof PathInjection::Source } diff --git a/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll b/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll index 964e75d39dc7..d1618a949042 100644 --- a/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll @@ -10,32 +10,6 @@ private import codeql.ruby.AST import codeql.ruby.DataFlow import codeql.ruby.TaintTracking -/** - * Provides a taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities. - * DEPRECATED: Use `ReflectedXssFlow` - */ -deprecated module ReflectedXss { - import XSS::ReflectedXss - - /** - * A taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities. - * DEPRECATED: Use `ReflectedXssFlow` - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ReflectedXSS" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - isAdditionalXssTaintStep(node1, node2) - } - } -} - private module ReflectedXssConfig implements DataFlow::ConfigSig { private import XSS::ReflectedXss as RX diff --git a/ruby/ql/lib/codeql/ruby/security/SensitiveGetQueryQuery.qll b/ruby/ql/lib/codeql/ruby/security/SensitiveGetQueryQuery.qll index d18b6949f105..d3fe93fa764a 100644 --- a/ruby/ql/lib/codeql/ruby/security/SensitiveGetQueryQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/SensitiveGetQueryQuery.qll @@ -10,27 +10,6 @@ private import ruby private import codeql.ruby.TaintTracking -/** - * Provides a taint-tracking configuration for detecting flow of query string - * data to sensitive actions in GET query request handlers. - * DEPRECATED: Use `SensitiveGetQueryFlow` - */ -deprecated module SensitiveGetQuery { - import SensitiveGetQueryCustomizations::SensitiveGetQuery - - /** - * A taint-tracking configuration for reasoning about use of sensitive data - * from a GET request query string. - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SensitiveGetQuery" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - } -} - private module SensitiveGetQueryConfig implements DataFlow::ConfigSig { import SensitiveGetQueryCustomizations::SensitiveGetQuery diff --git a/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryQuery.qll b/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryQuery.qll index 319bbc30d5d7..2e8aed1c0b87 100644 --- a/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryQuery.qll @@ -12,25 +12,6 @@ import codeql.ruby.TaintTracking import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting - * "Server side request forgery" vulnerabilities. - * DEPRECATED: Use `ServerSideRequestForgeryFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "ServerSideRequestForgery" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Sanitizer or - node instanceof StringConstCompareBarrier or - node instanceof StringConstArrayInclusionCallBarrier - } -} - private module ServerSideRequestForgeryConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll index 9225552a8400..40a9b603bf4e 100644 --- a/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll @@ -7,20 +7,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking import SqlInjectionCustomizations::SqlInjection -/** - * A taint-tracking configuration for detecting SQL injection vulnerabilities. - * DEPRECATED: Use `SqlInjectionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SqlInjectionConfiguration" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module SqlInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll index b07c3d584da0..8342c382cdb2 100644 --- a/ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/StackTraceExposureQuery.qll @@ -11,20 +11,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking private import StackTraceExposureCustomizations::StackTraceExposure -/** - * A taint-tracking configuration for detecting "stack trace exposure" vulnerabilities. - * DEPRECATED: Use `StackTraceExposureFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "StackTraceExposure" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module StackTraceExposureConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll b/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll index b10088af82ee..1231921649e7 100644 --- a/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll @@ -25,19 +25,3 @@ module TaintedFormatStringConfig implements DataFlow::ConfigSig { * Taint-tracking for format injections. */ module TaintedFormatStringFlow = TaintTracking::Global; - -/** - * DEPRECATED. Use the `TaintedFormatStringFlow` module instead. - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "TaintedFormatString" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof Sanitizer - } -} diff --git a/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll index 8cc26e189aa7..3e3610915496 100644 --- a/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll @@ -7,20 +7,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking import TemplateInjectionCustomizations::TemplateInjection -/** - * A taint-tracking configuration for detecting Server Side Template Injections vulnerabilities. - * DEPRECATED: Use `TemplateInjectionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "TemplateInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module TemplateInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeCodeConstructionQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeCodeConstructionQuery.qll index 32cc9a4f821f..06dc8797832a 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeCodeConstructionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeCodeConstructionQuery.qll @@ -12,28 +12,6 @@ import UnsafeCodeConstructionCustomizations::UnsafeCodeConstruction private import codeql.ruby.TaintTracking private import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting code constructed from library input vulnerabilities. - * DEPRECATED: Use `UnsafeCodeConstructionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeShellCommandConstruction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof StringConstCompareBarrier or - node instanceof StringConstArrayInclusionCallBarrier - } - - // override to require the path doesn't have unmatched return steps - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSourceCallContext - } -} - private module UnsafeCodeConstructionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll index 0c6e97f1fa05..ad7749d68aa6 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll @@ -11,25 +11,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking import UnsafeDeserializationCustomizations -/** - * A taint-tracking configuration for reasoning about unsafe deserialization. - * DEPRECATED: Use `UnsafeDeserializationFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeDeserialization" } - - override predicate isSource(DataFlow::Node source) { - source instanceof UnsafeDeserialization::Source - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserialization::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - super.isSanitizer(node) or - node instanceof UnsafeDeserialization::Sanitizer - } -} - private module UnsafeDeserializationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof UnsafeDeserialization::Source } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeHtmlConstructionQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeHtmlConstructionQuery.qll index 9d655a6d16a7..44e008cfa8b4 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeHtmlConstructionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeHtmlConstructionQuery.qll @@ -12,25 +12,6 @@ import UnsafeHtmlConstructionCustomizations::UnsafeHtmlConstruction private import codeql.ruby.TaintTracking private import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting unsafe HTML construction. - * DEPRECATED: Use `UnsafeHtmlConstructionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeHtmlConstruction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - // override to require the path doesn't have unmatched return steps - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSourceCallContext - } -} - private module UnsafeHtmlConstructionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeShellCommandConstructionQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeShellCommandConstructionQuery.qll index b4e0b8b6bb50..6e3ac947a514 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeShellCommandConstructionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeShellCommandConstructionQuery.qll @@ -13,29 +13,6 @@ private import codeql.ruby.TaintTracking private import CommandInjectionCustomizations::CommandInjection as CommandInjection private import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting shell command constructed from library input vulnerabilities. - * DEPRECATED: Use `UnsafeShellCommandConstructionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeShellCommandConstruction" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof CommandInjection::Sanitizer or // using all sanitizers from `rb/command-injection` - node instanceof StringConstCompareBarrier or - node instanceof StringConstArrayInclusionCallBarrier - } - - // override to require the path doesn't have unmatched return steps - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSourceCallContext - } -} - private module UnsafeShellCommandConstructionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/UrlRedirectQuery.qll b/ruby/ql/lib/codeql/ruby/security/UrlRedirectQuery.qll index 37334445aa76..6169de81269a 100644 --- a/ruby/ql/lib/codeql/ruby/security/UrlRedirectQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UrlRedirectQuery.qll @@ -12,24 +12,6 @@ import codeql.ruby.TaintTracking import UrlRedirectCustomizations import UrlRedirectCustomizations::UrlRedirect -/** - * A taint-tracking configuration for detecting "URL redirection" vulnerabilities. - * DEPRECATED: Use `UrlRedirectFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UrlRedirect" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - UrlRedirect::isAdditionalTaintStep(node1, node2) - } -} - private module UrlRedirectConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/regexp/MissingFullAnchorQuery.qll b/ruby/ql/lib/codeql/ruby/security/regexp/MissingFullAnchorQuery.qll index 19ac3600fa1e..febfa0712d9b 100644 --- a/ruby/ql/lib/codeql/ruby/security/regexp/MissingFullAnchorQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/regexp/MissingFullAnchorQuery.qll @@ -11,21 +11,6 @@ import ruby import codeql.ruby.TaintTracking import MissingFullAnchorCustomizations::MissingFullAnchor -/** - * A taint tracking configuration for reasoning about - * missing full-anchored regular expressions. - * DEPRECATED: Use `MissingFullAnchorFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "MissingFullAnchor" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } -} - private module MissingFullAnchorConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/ruby/ql/lib/codeql/ruby/security/regexp/PolynomialReDoSQuery.qll b/ruby/ql/lib/codeql/ruby/security/regexp/PolynomialReDoSQuery.qll index 934f8812019e..98a42fcf5e7c 100644 --- a/ruby/ql/lib/codeql/ruby/security/regexp/PolynomialReDoSQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/regexp/PolynomialReDoSQuery.qll @@ -10,30 +10,6 @@ private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking -/** - * Provides a taint-tracking configuration for detecting polynomial regular - * expression denial of service vulnerabilities. - * DEPRECATED: Use `PolynomialReDoSFlow` - */ -deprecated module PolynomialReDoS { - import PolynomialReDoSCustomizations::PolynomialReDoS - - /** - * A taint-tracking configuration for detecting polynomial regular expression - * denial of service vulnerabilities. - * DEPRECATED: Use `PolynomialReDoSFlow` - */ - deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "PolynomialReDoS" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - } -} - private module PolynomialReDoSConfig implements DataFlow::ConfigSig { private import PolynomialReDoSCustomizations::PolynomialReDoS diff --git a/ruby/ql/lib/codeql/ruby/security/regexp/RegExpInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/regexp/RegExpInjectionQuery.qll index 353c13a3c2dc..3e6f6f83ef8d 100644 --- a/ruby/ql/lib/codeql/ruby/security/regexp/RegExpInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/regexp/RegExpInjectionQuery.qll @@ -11,20 +11,6 @@ import codeql.ruby.TaintTracking import RegExpInjectionCustomizations import codeql.ruby.dataflow.BarrierGuards -/** - * A taint-tracking configuration for detecting regexp injection vulnerabilities. - * DEPRECATED: Use `RegExpInjectionFlow` - */ -deprecated class Configuration extends TaintTracking::Configuration { - Configuration() { this = "RegExpInjection" } - - override predicate isSource(DataFlow::Node source) { source instanceof RegExpInjection::Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof RegExpInjection::Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof RegExpInjection::Sanitizer } -} - private module RegExpInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RegExpInjection::Source } diff --git a/swift/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md b/swift/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md new file mode 100644 index 000000000000..d09ec528c99e --- /dev/null +++ b/swift/ql/lib/change-notes/2024-12-03-remove-dataflow-config-class-api.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API. diff --git a/swift/ql/lib/codeql/swift/dataflow/DataFlow.qll b/swift/ql/lib/codeql/swift/dataflow/DataFlow.qll index 670a94babd9d..fd99bfd1999d 100644 --- a/swift/ql/lib/codeql/swift/dataflow/DataFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/DataFlow.qll @@ -7,5 +7,5 @@ module DataFlow { private import codeql.dataflow.DataFlow private import codeql.swift.elements.Location import DataFlowMake - import internal.DataFlowImpl1 + import Public } diff --git a/swift/ql/lib/codeql/swift/dataflow/TaintTracking.qll b/swift/ql/lib/codeql/swift/dataflow/TaintTracking.qll index e46cd18abb4c..1998e25abd73 100644 --- a/swift/ql/lib/codeql/swift/dataflow/TaintTracking.qll +++ b/swift/ql/lib/codeql/swift/dataflow/TaintTracking.qll @@ -3,11 +3,10 @@ * global (inter-procedural) taint-tracking analyses. */ module TaintTracking { - import codeql.swift.dataflow.internal.tainttracking1.TaintTrackingParameter::Public + import codeql.swift.dataflow.internal.TaintTrackingPublic private import codeql.swift.dataflow.internal.DataFlowImplSpecific private import codeql.swift.dataflow.internal.TaintTrackingImplSpecific private import codeql.dataflow.TaintTracking private import codeql.swift.elements.Location import TaintFlowMake - import codeql.swift.dataflow.internal.tainttracking1.TaintTrackingImpl } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll deleted file mode 100644 index 17def0c431db..000000000000 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll +++ /dev/null @@ -1,361 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides a `Configuration` class backwards-compatible interface to the data - * flow library. - */ - -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -import DataFlowImplSpecific::Public -private import DataFlowImpl -import DataFlowImplCommonPublic -deprecated import FlowStateString -private import codeql.util.Unit - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural data flow analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the global data flow library must define its own unique extension - * of this abstract class. To create a configuration, extend this class with - * a subclass whose characteristic predicate is a unique singleton string. - * For example, write - * - * ```ql - * class MyAnalysisConfiguration extends DataFlow::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isBarrier`. - * // Optionally override `isAdditionalFlowStep`. - * } - * ``` - * Conceptually, this defines a graph where the nodes are `DataFlow::Node`s and - * the edges are those data-flow steps that preserve the value of the node - * along with any additional edges defined by `isAdditionalFlowStep`. - * Specifying nodes in `isBarrier` will remove those nodes from the graph, and - * specifying nodes in `isBarrierIn` and/or `isBarrierOut` will remove in-going - * and/or out-going edges from those nodes, respectively. - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but two classes extending - * `DataFlow::Configuration` should never depend on each other. One of them - * should instead depend on a `DataFlow2::Configuration`, a - * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. - */ -abstract deprecated class Configuration extends string { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(Node source) { none() } - - /** - * Holds if `source` is a relevant data flow source with the given initial - * `state`. - */ - predicate isSource(Node source, FlowState state) { none() } - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(Node sink) { none() } - - /** - * Holds if `sink` is a relevant data flow sink accepting `state`. - */ - predicate isSink(Node sink, FlowState state) { none() } - - /** - * Holds if data flow through `node` is prohibited. This completely removes - * `node` from the data flow graph. - */ - predicate isBarrier(Node node) { none() } - - /** - * Holds if data flow through `node` is prohibited when the flow state is - * `state`. - */ - predicate isBarrier(Node node, FlowState state) { none() } - - /** Holds if data flow into `node` is prohibited. */ - predicate isBarrierIn(Node node) { none() } - - /** Holds if data flow out of `node` is prohibited. */ - predicate isBarrierOut(Node node) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - * This step is only applicable in `state1` and updates the flow state to `state2`. - */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { - none() - } - - /** - * Holds if an arbitrary number of implicit read steps of content `c` may be - * taken at `node`. - */ - predicate allowImplicitRead(Node node, ContentSet c) { none() } - - /** - * Gets the virtual dispatch branching limit when calculating field flow. - * This can be overridden to a smaller value to improve performance (a - * value of 0 disables field flow), or a larger value to get more results. - */ - int fieldFlowBranchLimit() { result = 2 } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - * - * These features are generally not relevant for typical end-to-end data flow - * queries, but should only be used for constructing paths that need to - * somehow be pluggable in another path context. - */ - FlowFeature getAFeature() { none() } - - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ - predicate sourceGrouping(Node source, string sourceGroup) { none() } - - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ - predicate sinkGrouping(Node sink, string sinkGroup) { none() } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - */ - predicate hasFlow(Node source, Node sink) { hasFlow(source, sink, this) } - - /** - * Holds if data may flow from `source` to `sink` for this configuration. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowTo(Node sink) { hasFlowTo(sink, this) } - - /** - * Holds if data may flow from some source to `sink` for this configuration. - */ - predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) } - - /** - * Holds if hidden nodes should be included in the data flow graph. - * - * This feature should only be used for debugging or when the data flow graph - * is not visualized (for example in a `path-problem` query). - */ - predicate includeHiddenNodes() { none() } -} - -/** - * This class exists to prevent mutual recursion between the user-overridden - * member predicates of `Configuration` and the rest of the data-flow library. - * Good performance cannot be guaranteed in the presence of such recursion, so - * it should be replaced by using more than one copy of the data flow library. - */ -abstract deprecated private class ConfigurationRecursionPrevention extends Configuration { - bindingset[this] - ConfigurationRecursionPrevention() { any() } - - override predicate hasFlow(Node source, Node sink) { - strictcount(Node n | this.isSource(n)) < 0 - or - strictcount(Node n | this.isSource(n, _)) < 0 - or - strictcount(Node n | this.isSink(n)) < 0 - or - strictcount(Node n | this.isSink(n, _)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 - or - strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, _, n2, _)) < 0 - or - super.hasFlow(source, sink) - } -} - -deprecated private FlowState relevantState(Configuration config) { - config.isSource(_, result) or - config.isSink(_, result) or - config.isBarrier(_, result) or - config.isAdditionalFlowStep(_, result, _, _) or - config.isAdditionalFlowStep(_, _, _, result) -} - -private newtype TConfigState = - deprecated TMkConfigState(Configuration config, FlowState state) { - state = relevantState(config) or state instanceof FlowStateEmpty - } - -deprecated private Configuration getConfig(TConfigState state) { state = TMkConfigState(result, _) } - -deprecated private FlowState getState(TConfigState state) { state = TMkConfigState(_, result) } - -deprecated private predicate singleConfiguration() { 1 = strictcount(Configuration c) } - -deprecated private module Config implements FullStateConfigSig { - class FlowState = TConfigState; - - predicate isSource(Node source, FlowState state) { - getConfig(state).isSource(source, getState(state)) - or - getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty - } - - predicate isSink(Node sink) { none() } - - predicate isSink(Node sink, FlowState state) { - getConfig(state).isSink(sink, getState(state)) - or - getConfig(state).isSink(sink) and getState(state) instanceof FlowStateEmpty - } - - predicate isBarrier(Node node) { none() } - - predicate isBarrier(Node node, FlowState state) { - getConfig(state).isBarrier(node, getState(state)) or - getConfig(state).isBarrier(node) - } - - predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) } - - predicate isBarrierOut(Node node) { any(Configuration config).isBarrierOut(node) } - - predicate isBarrierIn(Node node, FlowState state) { none() } - - predicate isBarrierOut(Node node, FlowState state) { none() } - - predicate isAdditionalFlowStep(Node node1, Node node2, string model) { - singleConfiguration() and - any(Configuration config).isAdditionalFlowStep(node1, node2) and - model = "" - } - - predicate isAdditionalFlowStep( - Node node1, FlowState state1, Node node2, FlowState state2, string model - ) { - getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) and - model = "" - or - not singleConfiguration() and - getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 and - model = "" - } - - predicate allowImplicitRead(Node node, ContentSet c) { - any(Configuration config).allowImplicitRead(node, c) - } - - predicate neverSkip(Node node) { none() } - - int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } - - int accessPathLimit() { result = 5 } - - FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } - - predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() } - - predicate observeDiffInformedIncrementalMode() { none() } -} - -deprecated private import Impl as I - -/** - * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ -deprecated class PathNode instanceof I::PathNode { - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { result = super.getNode() } - - /** Gets the `FlowState` of this node. */ - deprecated final FlowState getState() { result = getState(super.getState()) } - - /** Gets the associated configuration. */ - deprecated final Configuration getConfiguration() { result = getConfig(super.getState()) } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getASuccessor() } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource() } - - /** Holds if this node is a grouping of source nodes. */ - final predicate isSourceGroup(string group) { super.isSourceGroup(group) } - - /** Holds if this node is a grouping of sink nodes. */ - final predicate isSinkGroup(string group) { super.isSinkGroup(group) } -} - -deprecated module PathGraph = I::PathGraph; - -deprecated private predicate hasFlow(Node source, Node sink, Configuration config) { - exists(PathNode source0, PathNode sink0 | - hasFlowPath(source0, sink0, config) and - source0.getNode() = source and - sink0.getNode() = sink - ) -} - -deprecated private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - I::flowPath(source, sink) and source.getConfiguration() = config -} - -deprecated private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } - -deprecated predicate flowsTo = hasFlow/3; diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll deleted file mode 100644 index 75e7856fd261..000000000000 --- a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ /dev/null @@ -1,168 +0,0 @@ -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * Provides an implementation of global (interprocedural) taint tracking. - * This file re-exports the local (intraprocedural) taint-tracking analysis - * from `TaintTrackingParameter::Public` and adds a global analysis, mainly - * exposed through the `Configuration` class. For some languages, this file - * exists in several identical copies, allowing queries to use multiple - * `Configuration` classes that depend on each other without introducing - * mutual recursion among those configurations. - */ - -import TaintTrackingParameter::Public -private import TaintTrackingParameter::Private - -/** - * DEPRECATED: Use `Global` and `GlobalWithState` instead. - * - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ```ql - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isSanitizerIn`. - * // Optionally override `isSanitizerOut`. - * // Optionally override `isSanitizerGuard`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ```ql - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on - * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking2::Configuration` or a - * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. - */ -abstract deprecated class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** - * Holds if `source` is a relevant taint source. - * - * The smaller this predicate is, the faster `hasFlow()` will converge. - */ - // overridden to provide taint-tracking specific qldoc - override predicate isSource(DataFlow::Node source) { none() } - - /** - * 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() } - - final override predicate isBarrier(DataFlow::Node node) { - this.isSanitizer(node) or - 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() } - - final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) } - - /** Holds if taint propagation out of `node` is prohibited. */ - predicate isSanitizerOut(DataFlow::Node node) { none() } - - final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - */ - predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - this.isAdditionalTaintStep(node1, node2) or - defaultAdditionalTaintStep(node1, node2, _) - } - - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps. - * 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::ContentSet c) { - ( - this.isSink(node) or - this.isSink(node, _) or - this.isAdditionalTaintStep(node, _) or - this.isAdditionalTaintStep(node, _, _, _) - ) and - defaultImplicitTaintRead(node, c) - } - - /** - * Holds if taint may flow from `source` to `sink` for this configuration. - */ - // overridden to provide taint-tracking specific qldoc - override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { - super.hasFlow(source, sink) - } -} diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingParameter.qll deleted file mode 100644 index 1cd9cab0e54e..000000000000 --- a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingParameter.qll +++ /dev/null @@ -1,7 +0,0 @@ -import codeql.swift.dataflow.internal.TaintTrackingPublic as Public - -module Private { - import codeql.swift.dataflow.DataFlow::DataFlow as DataFlow - import codeql.swift.dataflow.internal.DataFlowImpl as DataFlowInternal - import codeql.swift.dataflow.internal.TaintTrackingPrivate -}