mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
Merge branch 'main' into shared/add-location-to-typetracking-nodes
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
load("@tree_sitter_extractors_deps//:defs.bzl", "aliases", "all_crate_deps")
|
||||
load("//misc/bazel:rust.bzl", "codeql_rust_binary")
|
||||
load("//misc/bazel/3rdparty/tree_sitter_extractors_deps:defs.bzl", "aliases", "all_crate_deps")
|
||||
|
||||
exports_files(["Cargo.toml"])
|
||||
|
||||
codeql_rust_binary(
|
||||
name = "extractor",
|
||||
|
||||
@@ -5,16 +5,17 @@ version = "0.1.0"
|
||||
authors = ["GitHub"]
|
||||
edition = "2021"
|
||||
|
||||
# When updating these dependencies, run `misc/bazel/3rdparty/update_cargo_deps.sh`
|
||||
[dependencies]
|
||||
tree-sitter = ">= 0.23.0"
|
||||
tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template.git", rev = "62b0a6e45900a7dff7c37da95fec20a09968ba52" }
|
||||
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "a66579f70d6f50ffd81a16fc3d3358e2ac173c88" }
|
||||
clap = { version = "4.2", features = ["derive"] }
|
||||
tree-sitter-embedded-template = "0.23.2"
|
||||
tree-sitter-ruby = "0.23.1"
|
||||
clap = { version = "4.5", features = ["derive"] }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3.3", features = ["env-filter"] }
|
||||
rayon = "1.5.0"
|
||||
regex = "1.7.1"
|
||||
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
|
||||
rayon = "1.10.0"
|
||||
regex = "1.11.1"
|
||||
encoding = "0.2"
|
||||
lazy_static = "1.4.0"
|
||||
lazy_static = "1.5.0"
|
||||
|
||||
codeql-extractor = { path = "../../shared/tree-sitter-extractor" }
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
## 3.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* 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.
|
||||
|
||||
## 2.0.4
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 2.0.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 2.0.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `ExtractionError` class has been split into `ExtractionError` and `ExtractionWarning`, reporting extraction errors and warnings respectively.
|
||||
|
||||
## 2.0.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 2.0.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `ExtractionError` class has been split into `ExtractionError` and `ExtractionWarning`, reporting extraction errors and warnings respectively.
|
||||
3
ruby/ql/lib/change-notes/released/2.0.3.md
Normal file
3
ruby/ql/lib/change-notes/released/2.0.3.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 2.0.3
|
||||
|
||||
No user-facing changes.
|
||||
3
ruby/ql/lib/change-notes/released/2.0.4.md
Normal file
3
ruby/ql/lib/change-notes/released/2.0.4.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 2.0.4
|
||||
|
||||
No user-facing changes.
|
||||
5
ruby/ql/lib/change-notes/released/3.0.0.md
Normal file
5
ruby/ql/lib/change-notes/released/3.0.0.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 3.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* 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.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 2.0.1
|
||||
lastReleaseVersion: 3.0.0
|
||||
|
||||
@@ -13,5 +13,5 @@ module DataFlow {
|
||||
private import codeql.ruby.dataflow.internal.DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlow
|
||||
import DataFlowMake<Location, RubyDataFlow>
|
||||
import codeql.ruby.dataflow.internal.DataFlowImpl1
|
||||
import Public
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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<Location, RubyDataFlow, RubyTaintTracking>
|
||||
import codeql.ruby.dataflow.internal.tainttracking1.TaintTrackingImpl
|
||||
}
|
||||
|
||||
@@ -1,357 +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) {
|
||||
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
|
||||
getConfig(state2) = getConfig(state1)
|
||||
or
|
||||
not singleConfiguration() and
|
||||
getConfig(state1).isAdditionalFlowStep(node1, node2) and
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
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<Config> 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;
|
||||
@@ -1,357 +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) {
|
||||
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
|
||||
getConfig(state2) = getConfig(state1)
|
||||
or
|
||||
not singleConfiguration() and
|
||||
getConfig(state1).isAdditionalFlowStep(node1, node2) and
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
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<Config> 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;
|
||||
@@ -175,11 +175,9 @@ module LocalFlow {
|
||||
or
|
||||
node1 = node2.(ImplicitBlockArgumentNode).getParameterNode(true)
|
||||
or
|
||||
node1 =
|
||||
unique(FlowSummaryNode n1 |
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(n1.getSummaryNode(),
|
||||
node2.(FlowSummaryNode).getSummaryNode(), true, _)
|
||||
)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalMustFlowStep(node1
|
||||
.(FlowSummaryNode)
|
||||
.getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -829,7 +829,28 @@ class ContentSet extends TContentSet {
|
||||
this.isAny() and
|
||||
exists(result)
|
||||
or
|
||||
result = this.getAnElementReadContent()
|
||||
exists(Content elementContent | elementContent = this.getAnElementReadContent() |
|
||||
result = elementContent
|
||||
or
|
||||
// Do not distinguish symbol keys from string keys. This allows us to
|
||||
// give more precise summaries for something like `with_indifferent_access`,
|
||||
// and the amount of false-positive flow arising from this should be very
|
||||
// limited.
|
||||
elementContent =
|
||||
any(Content::KnownElementContent known, ConstantValue cv |
|
||||
cv = known.getIndex() and
|
||||
result.(Content::KnownElementContent).getIndex() =
|
||||
any(ConstantValue cv2 |
|
||||
cv2.(ConstantValue::ConstantSymbolValue).getStringlikeValue() =
|
||||
cv.(ConstantValue::ConstantStringValue).getStringlikeValue()
|
||||
or
|
||||
cv2.(ConstantValue::ConstantStringValue).getStringlikeValue() =
|
||||
cv.(ConstantValue::ConstantSymbolValue).getStringlikeValue()
|
||||
)
|
||||
|
|
||||
known
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -149,3 +149,37 @@ private module Cached {
|
||||
}
|
||||
|
||||
import Cached
|
||||
import SpeculativeTaintFlow
|
||||
|
||||
private module SpeculativeTaintFlow {
|
||||
private import codeql.ruby.dataflow.internal.DataFlowDispatch as DataFlowDispatch
|
||||
private import codeql.ruby.dataflow.internal.DataFlowPublic as DataFlowPublic
|
||||
|
||||
/**
|
||||
* Holds if the additional step from `src` to `sink` should be considered in
|
||||
* speculative taint flow exploration.
|
||||
*/
|
||||
predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
||||
exists(
|
||||
DataFlowDispatch::DataFlowCall call, MethodCall srcCall,
|
||||
DataFlowDispatch::ArgumentPosition argpos, MethodCall mc
|
||||
|
|
||||
// TODO: exclude neutrals and anything that has QL modeling.
|
||||
not exists(DataFlowDispatch::viableCallable(call)) and
|
||||
call.asCall().getExpr() = srcCall and
|
||||
src.(ArgumentNode).argumentOf(call, argpos) and
|
||||
call.asCall().getExpr() = mc and
|
||||
not mc instanceof Operation and
|
||||
not mc instanceof SetterMethodCall and
|
||||
not mc instanceof ElementReference
|
||||
|
|
||||
not argpos.isSelf() and
|
||||
sink.(DataFlowPublic::PostUpdateNode)
|
||||
.getPreUpdateNode()
|
||||
.(ArgumentNode)
|
||||
.argumentOf(call, any(DataFlowDispatch::ArgumentPosition qualpos | qualpos.isSelf()))
|
||||
or
|
||||
sink.(OutNode).getCall(_) = call
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -121,16 +121,6 @@ module ActiveSupport {
|
||||
* Extensions to the `Hash` class.
|
||||
*/
|
||||
module Hash {
|
||||
private class WithIndifferentAccessSummary extends SimpleSummarizedCallable {
|
||||
WithIndifferentAccessSummary() { this = "with_indifferent_access" }
|
||||
|
||||
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
||||
input = "Argument[self].Element[any]" and
|
||||
output = "ReturnValue.Element[any]" and
|
||||
preservesValue = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flow summary for `reverse_merge`, and its alias `with_defaults`.
|
||||
*/
|
||||
@@ -167,8 +157,9 @@ module ActiveSupport {
|
||||
}
|
||||
|
||||
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
||||
input = "Argument[self].Element[any]" and
|
||||
output = "ReturnValue.Element[?]" and
|
||||
// keys are considered equal modulo string/symbol in our implementation
|
||||
input = "Argument[self].WithElement[any]" and
|
||||
output = "ReturnValue" and
|
||||
preservesValue = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ module Cryptography {
|
||||
class PasswordHashingAlgorithm = CryptoAlgorithms::PasswordHashingAlgorithm;
|
||||
|
||||
/**
|
||||
* A data-flow node that is an application of a cryptographic algorithm. For example,
|
||||
* A data flow node that is an application of a cryptographic algorithm. For example,
|
||||
* encryption, decryption, signature-validation.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
@@ -40,7 +40,7 @@ module Cryptography {
|
||||
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
|
||||
CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() }
|
||||
|
||||
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
|
||||
/** Gets the data flow node where the cryptographic algorithm used in this operation is configured. */
|
||||
DataFlow::Node getInitialization() { result = super.getInitialization() }
|
||||
|
||||
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
|
||||
@@ -61,14 +61,14 @@ module Cryptography {
|
||||
/** Provides classes for modeling new applications of a cryptographic algorithms. */
|
||||
module CryptographicOperation {
|
||||
/**
|
||||
* A data-flow node that is an application of a cryptographic algorithm. For example,
|
||||
* A data flow node that is an application of a cryptographic algorithm. For example,
|
||||
* encryption, decryption, signature-validation.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `CryptographicOperation` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
|
||||
/** Gets the data flow node where the cryptographic algorithm used in this operation is configured. */
|
||||
abstract DataFlow::Node getInitialization();
|
||||
|
||||
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
|
||||
@@ -118,14 +118,14 @@ module Http {
|
||||
/** Provides classes for modeling HTTP clients. */
|
||||
module Client {
|
||||
/**
|
||||
* A data-flow node that makes an outgoing HTTP request.
|
||||
* A data flow node that makes an outgoing HTTP request.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `Http::Client::Request::Range` instead.
|
||||
*/
|
||||
class Request extends DataFlow::Node instanceof Request::Range {
|
||||
/**
|
||||
* Gets a data-flow node that contributes to the URL of the request.
|
||||
* Gets a data flow node that contributes to the URL of the request.
|
||||
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
|
||||
*/
|
||||
DataFlow::Node getAUrlPart() { result = super.getAUrlPart() }
|
||||
@@ -150,14 +150,14 @@ module Http {
|
||||
/** Provides a class for modeling new HTTP requests. */
|
||||
module Request {
|
||||
/**
|
||||
* A data-flow node that makes an outgoing HTTP request.
|
||||
* A data flow node that makes an outgoing HTTP request.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `Http::Client::Request` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/**
|
||||
* Gets a data-flow node that contributes to the URL of the request.
|
||||
* Gets a data flow node that contributes to the URL of the request.
|
||||
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
|
||||
*/
|
||||
abstract DataFlow::Node getAUrlPart();
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -23,19 +23,3 @@ module HttpToFileAccessConfig implements DataFlow::ConfigSig {
|
||||
* Taint tracking for writing user-controlled data to files.
|
||||
*/
|
||||
module HttpToFileAccessFlow = TaintTracking::Global<HttpToFileAccessConfig>;
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -25,19 +25,3 @@ module TaintedFormatStringConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for format injections.
|
||||
*/
|
||||
module TaintedFormatStringFlow = TaintTracking::Global<TaintedFormatStringConfig>;
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/ruby-all
|
||||
version: 2.0.2-dev
|
||||
version: 3.0.1-dev
|
||||
groups: ruby
|
||||
extractor: ruby
|
||||
dbscheme: ruby.dbscheme
|
||||
|
||||
21
ruby/ql/lib/utils/test/InlineExpectationsTestQuery.ql
Normal file
21
ruby/ql/lib/utils/test/InlineExpectationsTestQuery.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @kind test-postprocess
|
||||
*/
|
||||
|
||||
private import ruby
|
||||
private import codeql.util.test.InlineExpectationsTest as T
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import T::TestPostProcessing
|
||||
import T::TestPostProcessing::Make<Impl, Input>
|
||||
|
||||
private module Input implements T::TestPostProcessing::InputSig<Impl> {
|
||||
string getRelativeUrl(Location location) {
|
||||
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
|
||||
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
|
||||
f = location.getFile()
|
||||
|
|
||||
result =
|
||||
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ private import codeql.ruby.frameworks.data.internal.ApiGraphModelsExtensions as
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
|
||||
private module FlowTestImpl implements InputSig<Location, RubyDataFlow> {
|
||||
import TestUtilities.InlineFlowTestUtil
|
||||
import utils.test.InlineFlowTestUtil
|
||||
|
||||
bindingset[src, sink]
|
||||
string getArgString(DataFlow::Node src, DataFlow::Node sink) {
|
||||
@@ -1,6 +1,6 @@
|
||||
import ruby
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import TestUtilities.InlineFlowTestUtil
|
||||
import utils.test.InlineExpectationsTest
|
||||
import utils.test.InlineFlowTestUtil
|
||||
private import codeql.ruby.typetracking.TypeTracking
|
||||
|
||||
private DataFlow::LocalSourceNode track(TypeTracker t, DataFlow::CallNode source) {
|
||||
@@ -1,3 +1,21 @@
|
||||
## 1.1.8
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.1.7
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.1.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.1.5
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `rb/diagnostics/extraction-errors` diagnostic query has been split into `rb/diagnostics/extraction-errors` and `rb/diagnostics/extraction-warnings`, counting extraction errors and warnings respectively.
|
||||
|
||||
## 1.1.4
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 1.1.5
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `rb/diagnostics/extraction-errors` diagnostic query has been split into `rb/diagnostics/extraction-errors` and `rb/diagnostics/extraction-warnings`, counting extraction errors and warnings respectively.
|
||||
3
ruby/ql/src/change-notes/released/1.1.6.md
Normal file
3
ruby/ql/src/change-notes/released/1.1.6.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.1.6
|
||||
|
||||
No user-facing changes.
|
||||
3
ruby/ql/src/change-notes/released/1.1.7.md
Normal file
3
ruby/ql/src/change-notes/released/1.1.7.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.1.7
|
||||
|
||||
No user-facing changes.
|
||||
3
ruby/ql/src/change-notes/released/1.1.8.md
Normal file
3
ruby/ql/src/change-notes/released/1.1.8.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.1.8
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.1.4
|
||||
lastReleaseVersion: 1.1.8
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/ruby-queries
|
||||
version: 1.1.5-dev
|
||||
version: 1.1.9-dev
|
||||
groups:
|
||||
- ruby
|
||||
- queries
|
||||
|
||||
@@ -16,20 +16,9 @@
|
||||
|
||||
private import codeql.ruby.AST
|
||||
private import codeql.ruby.security.CodeInjectionQuery
|
||||
import CodeInjectionFlow::PathGraph
|
||||
import DataFlow::DeduplicatePathGraph<CodeInjectionFlow::PathNode, CodeInjectionFlow::PathGraph>
|
||||
|
||||
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, Source sourceNode
|
||||
where
|
||||
CodeInjectionFlow::flowPath(source, sink) and
|
||||
sourceNode = source.getNode() and
|
||||
// removing duplications of the same path, but different flow-labels.
|
||||
sink =
|
||||
min(CodeInjectionFlow::PathNode otherSink |
|
||||
CodeInjectionFlow::flowPath(any(CodeInjectionFlow::PathNode s | s.getNode() = sourceNode),
|
||||
otherSink) and
|
||||
otherSink.getNode() = sink.getNode()
|
||||
|
|
||||
otherSink order by otherSink.getState().getStringRepresentation()
|
||||
)
|
||||
select sink.getNode(), source, sink, "This code execution depends on a $@.", sourceNode,
|
||||
from PathNode source, PathNode sink
|
||||
where CodeInjectionFlow::flowPath(source.getAnOriginalPathNode(), sink.getAnOriginalPathNode())
|
||||
select sink.getNode(), source, sink, "This code execution depends on a $@.", source.getNode(),
|
||||
"user-provided value"
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.Concepts
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import utils.test.InlineExpectationsTest
|
||||
|
||||
module CryptographicOperationTest implements TestSig {
|
||||
string getARelevantTag() {
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
testFailures
|
||||
failures
|
||||
|
||||
@@ -3,7 +3,7 @@ import codeql.dataflow.internal.AccessPathSyntax
|
||||
import codeql.ruby.ast.internal.TreeSitter
|
||||
import codeql.ruby.frameworks.data.internal.ApiGraphModels as ApiGraphModels
|
||||
import codeql.ruby.ApiGraphs
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import utils.test.InlineExpectationsTest
|
||||
|
||||
private predicate accessPathRange(string s) { hasExpectationWithValue(_, s) }
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.CFG
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import ValueFlow::PathGraph
|
||||
|
||||
|
||||
@@ -1,37 +1,36 @@
|
||||
testFailures
|
||||
| array_flow.rb:107:10:107:13 | ...[...] | Unexpected result: hasValueFlow=11.2 |
|
||||
| array_flow.rb:179:28:179:46 | # $ hasValueFlow=19 | Missing result:hasValueFlow=19 |
|
||||
| array_flow.rb:180:28:180:46 | # $ hasValueFlow=19 | Missing result:hasValueFlow=19 |
|
||||
| array_flow.rb:179:28:179:46 | # $ hasValueFlow=19 | Missing result: hasValueFlow=19 |
|
||||
| array_flow.rb:180:28:180:46 | # $ hasValueFlow=19 | Missing result: hasValueFlow=19 |
|
||||
| array_flow.rb:226:10:226:13 | ...[...] | Unexpected result: hasValueFlow=25 |
|
||||
| array_flow.rb:319:10:319:13 | ...[...] | Unexpected result: hasValueFlow=36.1 |
|
||||
| array_flow.rb:320:10:320:13 | ...[...] | Unexpected result: hasValueFlow=36.1 |
|
||||
| array_flow.rb:321:10:321:13 | ...[...] | Unexpected result: hasValueFlow=36.1 |
|
||||
| array_flow.rb:328:10:328:13 | ...[...] | Unexpected result: hasValueFlow=37.1 |
|
||||
| array_flow.rb:360:22:360:42 | # $ hasValueFlow=40.2 | Missing result:hasValueFlow=40.2 |
|
||||
| array_flow.rb:360:22:360:42 | # $ hasValueFlow=40.2 | Missing result: hasValueFlow=40.2 |
|
||||
| array_flow.rb:486:10:486:13 | ...[...] | Unexpected result: hasValueFlow=54.2 |
|
||||
| array_flow.rb:490:10:490:13 | ...[...] | Unexpected result: hasValueFlow=54.2 |
|
||||
| array_flow.rb:490:10:490:13 | ...[...] | Unexpected result: hasValueFlow=54.3 |
|
||||
| array_flow.rb:494:10:494:13 | ...[...] | Unexpected result: hasValueFlow=54.2 |
|
||||
| array_flow.rb:494:10:494:13 | ...[...] | Unexpected result: hasValueFlow=54.3 |
|
||||
| array_flow.rb:586:16:586:34 | # $ hasValueFlow=63 | Missing result:hasValueFlow=63 |
|
||||
| array_flow.rb:591:19:591:37 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 |
|
||||
| array_flow.rb:593:16:593:34 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 |
|
||||
| array_flow.rb:594:19:594:47 | # $ SPURIOUS: hasValueFlow=64 | Fixed spurious result:hasValueFlow=64 |
|
||||
| array_flow.rb:595:16:595:34 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 |
|
||||
| array_flow.rb:596:19:596:47 | # $ SPURIOUS: hasValueFlow=64 | Fixed spurious result:hasValueFlow=64 |
|
||||
| array_flow.rb:586:16:586:34 | # $ hasValueFlow=63 | Missing result: hasValueFlow=63 |
|
||||
| array_flow.rb:591:19:591:37 | # $ hasValueFlow=64 | Missing result: hasValueFlow=64 |
|
||||
| array_flow.rb:593:16:593:34 | # $ hasValueFlow=64 | Missing result: hasValueFlow=64 |
|
||||
| array_flow.rb:594:19:594:47 | # $ SPURIOUS: hasValueFlow=64 | Fixed spurious result: hasValueFlow=64 |
|
||||
| array_flow.rb:595:16:595:34 | # $ hasValueFlow=64 | Missing result: hasValueFlow=64 |
|
||||
| array_flow.rb:596:19:596:47 | # $ SPURIOUS: hasValueFlow=64 | Fixed spurious result: hasValueFlow=64 |
|
||||
| array_flow.rb:659:10:659:13 | ...[...] | Unexpected result: hasValueFlow=70.1 |
|
||||
| array_flow.rb:664:10:664:13 | ...[...] | Unexpected result: hasValueFlow=70.1 |
|
||||
| array_flow.rb:871:18:871:36 | # $ hasValueFlow=87 | Missing result:hasValueFlow=87 |
|
||||
| array_flow.rb:872:18:872:36 | # $ hasValueFlow=87 | Missing result:hasValueFlow=87 |
|
||||
| array_flow.rb:871:18:871:36 | # $ hasValueFlow=87 | Missing result: hasValueFlow=87 |
|
||||
| array_flow.rb:872:18:872:36 | # $ hasValueFlow=87 | Missing result: hasValueFlow=87 |
|
||||
| array_flow.rb:928:10:928:13 | ...[...] | Unexpected result: hasValueFlow=90.1 |
|
||||
| array_flow.rb:939:18:939:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.1 |
|
||||
| array_flow.rb:939:18:939:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.2 |
|
||||
| array_flow.rb:939:18:939:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.3 |
|
||||
| array_flow.rb:940:18:940:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.1 |
|
||||
| array_flow.rb:940:18:940:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.2 |
|
||||
| array_flow.rb:940:18:940:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.3 |
|
||||
| array_flow.rb:957:28:957:46 | # $ hasValueFlow=93 | Missing result:hasValueFlow=93 |
|
||||
| array_flow.rb:958:28:958:46 | # $ hasValueFlow=93 | Missing result:hasValueFlow=93 |
|
||||
| array_flow.rb:939:18:939:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result: hasValueFlow=91.1 |
|
||||
| array_flow.rb:939:18:939:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result: hasValueFlow=91.2 |
|
||||
| array_flow.rb:939:18:939:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result: hasValueFlow=91.3 |
|
||||
| array_flow.rb:940:18:940:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result: hasValueFlow=91.1 |
|
||||
| array_flow.rb:940:18:940:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result: hasValueFlow=91.2 |
|
||||
| array_flow.rb:940:18:940:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result: hasValueFlow=91.3 |
|
||||
| array_flow.rb:957:28:957:46 | # $ hasValueFlow=93 | Missing result: hasValueFlow=93 |
|
||||
| array_flow.rb:958:28:958:46 | # $ hasValueFlow=93 | Missing result: hasValueFlow=93 |
|
||||
| array_flow.rb:1099:10:1099:13 | ...[...] | Unexpected result: hasValueFlow=105.2 |
|
||||
| array_flow.rb:1100:10:1100:13 | ...[...] | Unexpected result: hasValueFlow=105.3 |
|
||||
| array_flow.rb:1110:10:1110:13 | ...[...] | Unexpected result: hasValueFlow=105.2 |
|
||||
@@ -53,16 +52,15 @@ testFailures
|
||||
| array_flow.rb:1346:10:1346:13 | ...[...] | Unexpected result: hasValueFlow=112.1 |
|
||||
| array_flow.rb:1457:10:1457:13 | ...[...] | Unexpected result: hasValueFlow=121.2 |
|
||||
| array_flow.rb:1458:10:1458:13 | ...[...] | Unexpected result: hasValueFlow=121.2 |
|
||||
| array_flow.rb:1512:18:1512:39 | # $ hasValueFlow=128.1 | Missing result:hasValueFlow=128.1 |
|
||||
| array_flow.rb:1513:18:1513:39 | # $ hasValueFlow=128.2 | Missing result:hasValueFlow=128.2 |
|
||||
| array_flow.rb:1514:18:1514:39 | # $ hasValueFlow=128.3 | Missing result:hasValueFlow=128.3 |
|
||||
| array_flow.rb:1512:18:1512:39 | # $ hasValueFlow=128.1 | Missing result: hasValueFlow=128.1 |
|
||||
| array_flow.rb:1513:18:1513:39 | # $ hasValueFlow=128.2 | Missing result: hasValueFlow=128.2 |
|
||||
| array_flow.rb:1514:18:1514:39 | # $ hasValueFlow=128.3 | Missing result: hasValueFlow=128.3 |
|
||||
| array_flow.rb:1565:10:1565:13 | ...[...] | Unexpected result: hasValueFlow=132.1 |
|
||||
| array_flow.rb:1601:18:1601:39 | # $ hasValueFlow=134.3 | Missing result:hasValueFlow=134.3 |
|
||||
| array_flow.rb:1602:18:1602:39 | # $ hasValueFlow=134.2 | Missing result:hasValueFlow=134.2 |
|
||||
| array_flow.rb:1603:18:1603:39 | # $ hasValueFlow=134.1 | Missing result:hasValueFlow=134.1 |
|
||||
| array_flow.rb:1623:19:1623:40 | # $ hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 |
|
||||
| array_flow.rb:1626:19:1626:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 |
|
||||
| array_flow.rb:1626:19:1626:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result:hasValueFlow=136.2 |
|
||||
| array_flow.rb:1627:19:1627:40 | # $ hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 |
|
||||
| array_flow.rb:1699:13:1699:32 | # $ hasValueFlow=143 | Missing result:hasValueFlow=143 |
|
||||
failures
|
||||
| array_flow.rb:1601:18:1601:39 | # $ hasValueFlow=134.3 | Missing result: hasValueFlow=134.3 |
|
||||
| array_flow.rb:1602:18:1602:39 | # $ hasValueFlow=134.2 | Missing result: hasValueFlow=134.2 |
|
||||
| array_flow.rb:1603:18:1603:39 | # $ hasValueFlow=134.1 | Missing result: hasValueFlow=134.1 |
|
||||
| array_flow.rb:1623:19:1623:40 | # $ hasValueFlow=136.1 | Missing result: hasValueFlow=136.1 |
|
||||
| array_flow.rb:1626:19:1626:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result: hasValueFlow=136.1 |
|
||||
| array_flow.rb:1626:19:1626:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result: hasValueFlow=136.2 |
|
||||
| array_flow.rb:1627:19:1627:40 | # $ hasValueFlow=136.1 | Missing result: hasValueFlow=136.1 |
|
||||
| array_flow.rb:1699:13:1699:32 | # $ hasValueFlow=143 | Missing result: hasValueFlow=143 |
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
// only that type-tracking cannot follow the flow in your test. If the dataflow
|
||||
// test (`array-flow.ql`) shows no failures, then that may be sufficient
|
||||
// (depending on your use case).
|
||||
import TestUtilities.InlineTypeTrackingFlowTest
|
||||
import utils.test.InlineTypeTrackingFlowTest
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.CFG
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import codeql.ruby.dataflow.BarrierGuards
|
||||
import PathGraph
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
testFailures
|
||||
failures
|
||||
newStyleBarrierGuards
|
||||
| barrier-guards.rb:3:16:4:19 | [input] SSA phi read(foo) |
|
||||
| barrier-guards.rb:4:5:4:7 | foo |
|
||||
|
||||
@@ -5,7 +5,7 @@ import codeql.ruby.controlflow.CfgNodes
|
||||
import codeql.ruby.controlflow.ControlFlowGraph
|
||||
import codeql.ruby.controlflow.BasicBlocks
|
||||
import codeql.ruby.DataFlow
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import utils.test.InlineExpectationsTest
|
||||
|
||||
query predicate newStyleBarrierGuards(DataFlow::Node n) {
|
||||
n instanceof StringConstCompareBarrier or
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.DataFlow
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import TaintFlow::PathGraph
|
||||
import codeql.ruby.dataflow.internal.DataFlowDispatch as DataFlowDispatch
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.CFG
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import ValueFlowTest<DefaultFlowConfig>
|
||||
import ValueFlow::PathGraph
|
||||
|
||||
|
||||
@@ -458,22 +458,40 @@ edges
|
||||
| semantics.rb:263:14:263:14 | h [element :foo] | semantics.rb:263:10:263:15 | call to s31 | provenance | |
|
||||
| semantics.rb:263:14:263:14 | h [element] | semantics.rb:263:10:263:15 | call to s31 | provenance | |
|
||||
| semantics.rb:263:14:263:14 | h [element] | semantics.rb:263:10:263:15 | call to s31 | provenance | |
|
||||
| semantics.rb:267:5:267:5 | [post] h [element :foo] | semantics.rb:268:5:268:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:267:5:267:5 | [post] h [element :foo] | semantics.rb:268:5:268:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:267:15:267:25 | call to source | semantics.rb:267:5:267:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:267:15:267:25 | call to source | semantics.rb:267:5:267:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element :foo] | semantics.rb:269:5:269:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element :foo] | semantics.rb:269:5:269:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element foo] | semantics.rb:269:5:269:5 | h [element foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element foo] | semantics.rb:269:5:269:5 | h [element foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | h [element :foo] | semantics.rb:268:5:268:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | h [element :foo] | semantics.rb:268:5:268:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:268:16:268:26 | call to source | semantics.rb:268:5:268:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:268:16:268:26 | call to source | semantics.rb:268:5:268:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element :foo] | semantics.rb:270:5:270:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element :foo] | semantics.rb:270:5:270:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element foo] | semantics.rb:270:5:270:5 | h [element foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element foo] | semantics.rb:270:5:270:5 | h [element foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | h [element :foo] | semantics.rb:269:5:269:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | h [element :foo] | semantics.rb:269:5:269:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | h [element foo] | semantics.rb:269:5:269:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | h [element foo] | semantics.rb:269:5:269:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element :foo] | semantics.rb:273:14:273:14 | h [element :foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element :foo] | semantics.rb:273:14:273:14 | h [element :foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element foo] | semantics.rb:273:14:273:14 | h [element foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element foo] | semantics.rb:273:14:273:14 | h [element foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | h [element :foo] | semantics.rb:270:5:270:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | h [element :foo] | semantics.rb:270:5:270:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | h [element foo] | semantics.rb:270:5:270:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | h [element foo] | semantics.rb:270:5:270:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:271:5:271:5 | [post] h [element] | semantics.rb:273:14:273:14 | h [element] | provenance | |
|
||||
| semantics.rb:271:5:271:5 | [post] h [element] | semantics.rb:273:14:273:14 | h [element] | provenance | |
|
||||
| semantics.rb:271:12:271:22 | call to source | semantics.rb:271:5:271:5 | [post] h [element] | provenance | |
|
||||
| semantics.rb:271:12:271:22 | call to source | semantics.rb:271:5:271:5 | [post] h [element] | provenance | |
|
||||
| semantics.rb:273:14:273:14 | h [element :foo] | semantics.rb:273:10:273:15 | call to s32 | provenance | |
|
||||
| semantics.rb:273:14:273:14 | h [element :foo] | semantics.rb:273:10:273:15 | call to s32 | provenance | |
|
||||
| semantics.rb:273:14:273:14 | h [element foo] | semantics.rb:273:10:273:15 | call to s32 | provenance | |
|
||||
| semantics.rb:273:14:273:14 | h [element foo] | semantics.rb:273:10:273:15 | call to s32 | provenance | |
|
||||
| semantics.rb:273:14:273:14 | h [element] | semantics.rb:273:10:273:15 | call to s32 | provenance | |
|
||||
@@ -538,6 +556,8 @@ edges
|
||||
| semantics.rb:291:10:291:10 | x [element :foo] | semantics.rb:291:10:291:16 | ...[...] | provenance | |
|
||||
| semantics.rb:293:10:293:10 | x [element :foo] | semantics.rb:293:10:293:13 | ...[...] | provenance | |
|
||||
| semantics.rb:293:10:293:10 | x [element :foo] | semantics.rb:293:10:293:13 | ...[...] | provenance | |
|
||||
| semantics.rb:297:5:297:5 | x [element foo] | semantics.rb:298:10:298:10 | x [element foo] | provenance | |
|
||||
| semantics.rb:297:5:297:5 | x [element foo] | semantics.rb:298:10:298:10 | x [element foo] | provenance | |
|
||||
| semantics.rb:297:5:297:5 | x [element foo] | semantics.rb:299:10:299:10 | x [element foo] | provenance | |
|
||||
| semantics.rb:297:5:297:5 | x [element foo] | semantics.rb:299:10:299:10 | x [element foo] | provenance | |
|
||||
| semantics.rb:297:5:297:5 | x [element foo] | semantics.rb:301:10:301:10 | x [element foo] | provenance | |
|
||||
@@ -546,6 +566,8 @@ edges
|
||||
| semantics.rb:297:9:297:24 | call to s36 [element foo] | semantics.rb:297:5:297:5 | x [element foo] | provenance | |
|
||||
| semantics.rb:297:13:297:23 | call to source | semantics.rb:297:9:297:24 | call to s36 [element foo] | provenance | |
|
||||
| semantics.rb:297:13:297:23 | call to source | semantics.rb:297:9:297:24 | call to s36 [element foo] | provenance | |
|
||||
| semantics.rb:298:10:298:10 | x [element foo] | semantics.rb:298:10:298:16 | ...[...] | provenance | |
|
||||
| semantics.rb:298:10:298:10 | x [element foo] | semantics.rb:298:10:298:16 | ...[...] | provenance | |
|
||||
| semantics.rb:299:10:299:10 | x [element foo] | semantics.rb:299:10:299:17 | ...[...] | provenance | |
|
||||
| semantics.rb:299:10:299:10 | x [element foo] | semantics.rb:299:10:299:17 | ...[...] | provenance | |
|
||||
| semantics.rb:301:10:301:10 | x [element foo] | semantics.rb:301:10:301:13 | ...[...] | provenance | |
|
||||
@@ -1616,16 +1638,32 @@ nodes
|
||||
| semantics.rb:263:14:263:14 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:263:14:263:14 | h [element] | semmle.label | h [element] |
|
||||
| semantics.rb:263:14:263:14 | h [element] | semmle.label | h [element] |
|
||||
| semantics.rb:267:5:267:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:267:5:267:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:267:15:267:25 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:267:15:267:25 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:268:5:268:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:268:5:268:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:268:16:268:26 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:268:16:268:26 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:269:5:269:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:269:5:269:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:269:5:269:5 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:269:5:269:5 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:270:5:270:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:270:5:270:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:270:5:270:5 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:270:5:270:5 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:271:5:271:5 | [post] h [element] | semmle.label | [post] h [element] |
|
||||
@@ -1634,6 +1672,8 @@ nodes
|
||||
| semantics.rb:271:12:271:22 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:273:10:273:15 | call to s32 | semmle.label | call to s32 |
|
||||
| semantics.rb:273:10:273:15 | call to s32 | semmle.label | call to s32 |
|
||||
| semantics.rb:273:14:273:14 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:273:14:273:14 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:273:14:273:14 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:273:14:273:14 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:273:14:273:14 | h [element] | semmle.label | h [element] |
|
||||
@@ -1708,6 +1748,10 @@ nodes
|
||||
| semantics.rb:297:9:297:24 | call to s36 [element foo] | semmle.label | call to s36 [element foo] |
|
||||
| semantics.rb:297:13:297:23 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:297:13:297:23 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:298:10:298:10 | x [element foo] | semmle.label | x [element foo] |
|
||||
| semantics.rb:298:10:298:10 | x [element foo] | semmle.label | x [element foo] |
|
||||
| semantics.rb:298:10:298:16 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:298:10:298:16 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:299:10:299:10 | x [element foo] | semmle.label | x [element foo] |
|
||||
| semantics.rb:299:10:299:10 | x [element foo] | semmle.label | x [element foo] |
|
||||
| semantics.rb:299:10:299:17 | ...[...] | semmle.label | ...[...] |
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import PathGraph
|
||||
private import codeql.ruby.dataflow.FlowSummary
|
||||
|
||||
@@ -270,7 +270,7 @@ def m32(h, i)
|
||||
h[1] = source("d")
|
||||
h[i] = source("e")
|
||||
|
||||
sink s32(h) # $ hasValueFlow=b hasValueFlow=e
|
||||
sink s32(h) # $ hasValueFlow=b $ hasValueFlow=e $ SPURIOUS: hasValueFlow=a
|
||||
end
|
||||
|
||||
def m33(h, i)
|
||||
@@ -295,7 +295,7 @@ end
|
||||
|
||||
def m36(h, i)
|
||||
x = s36(source("a"))
|
||||
sink x[:foo]
|
||||
sink x[:foo] # $ SPURIOUS: hasValueFlow=a
|
||||
sink x["foo"] # $ hasValueFlow=a
|
||||
sink x[:bar]
|
||||
sink x[i] # $ hasValueFlow=a
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.DataFlow
|
||||
private import TestUtilities.InlineFlowTest
|
||||
private import utils.test.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import TaintFlow::PathGraph
|
||||
|
||||
|
||||
@@ -1,33 +1,31 @@
|
||||
testFailures
|
||||
| blocks.rb:4:10:4:10 | r | Fixed missing result:hasValueFlow=1 |
|
||||
| captured_variables.rb:50:10:50:10 | x | Fixed missing result:hasValueFlow=2 |
|
||||
| captured_variables.rb:68:25:68:68 | # $ hasValueFlow=3 $ MISSING: hasValueFlow=4 | Missing result:hasValueFlow=3 |
|
||||
| captured_variables.rb:72:21:72:66 | # $ hasValueFlow=4 $ SPURIOUS: hasValueFlow=3 | Fixed spurious result:hasValueFlow=3 |
|
||||
| captured_variables.rb:72:21:72:66 | # $ hasValueFlow=4 $ SPURIOUS: hasValueFlow=3 | Missing result:hasValueFlow=4 |
|
||||
| captured_variables.rb:83:21:83:38 | # $ hasValueFlow=5 | Missing result:hasValueFlow=5 |
|
||||
| blocks.rb:4:10:4:10 | r | Fixed missing result: hasValueFlow=1 |
|
||||
| captured_variables.rb:50:10:50:10 | x | Fixed missing result: hasValueFlow=2 |
|
||||
| captured_variables.rb:68:25:68:68 | # $ hasValueFlow=3 $ MISSING: hasValueFlow=4 | Missing result: hasValueFlow=3 |
|
||||
| captured_variables.rb:72:21:72:66 | # $ hasValueFlow=4 $ SPURIOUS: hasValueFlow=3 | Fixed spurious result: hasValueFlow=3 |
|
||||
| captured_variables.rb:72:21:72:66 | # $ hasValueFlow=4 $ SPURIOUS: hasValueFlow=3 | Missing result: hasValueFlow=4 |
|
||||
| captured_variables.rb:83:21:83:38 | # $ hasValueFlow=5 | Missing result: hasValueFlow=5 |
|
||||
| captured_variables.rb:87:10:87:10 | y | Unexpected result: hasValueFlow=7 |
|
||||
| captured_variables.rb:112:18:112:18 | x | Unexpected result: hasValueFlow=11 |
|
||||
| captured_variables.rb:126:14:126:14 | x | Fixed missing result:hasValueFlow=12 |
|
||||
| captured_variables.rb:154:17:154:35 | # $ hasValueFlow=13 | Missing result:hasValueFlow=13 |
|
||||
| instance_variables.rb:20:16:20:33 | # $ hasValueFlow=7 | Missing result:hasValueFlow=7 |
|
||||
| instance_variables.rb:36:36:36:54 | # $ hasValueFlow=34 | Missing result:hasValueFlow=34 |
|
||||
| instance_variables.rb:39:36:39:54 | # $ hasValueFlow=35 | Missing result:hasValueFlow=35 |
|
||||
| captured_variables.rb:126:14:126:14 | x | Fixed missing result: hasValueFlow=12 |
|
||||
| captured_variables.rb:154:17:154:35 | # $ hasValueFlow=13 | Missing result: hasValueFlow=13 |
|
||||
| instance_variables.rb:20:16:20:33 | # $ hasValueFlow=7 | Missing result: hasValueFlow=7 |
|
||||
| instance_variables.rb:36:36:36:54 | # $ hasValueFlow=34 | Missing result: hasValueFlow=34 |
|
||||
| instance_variables.rb:39:36:39:54 | # $ hasValueFlow=35 | Missing result: hasValueFlow=35 |
|
||||
| instance_variables.rb:49:14:49:14 | x | Unexpected result: hasValueFlow=30 |
|
||||
| instance_variables.rb:49:14:49:14 | x | Unexpected result: hasValueFlow=35 |
|
||||
| instance_variables.rb:55:21:55:39 | # $ hasValueFlow=42 | Missing result:hasValueFlow=42 |
|
||||
| instance_variables.rb:67:22:67:40 | # $ hasValueFlow=21 | Missing result:hasValueFlow=21 |
|
||||
| instance_variables.rb:71:18:71:36 | # $ hasValueFlow=22 | Missing result:hasValueFlow=22 |
|
||||
| instance_variables.rb:79:22:79:40 | # $ hasValueFlow=24 | Missing result:hasValueFlow=24 |
|
||||
| instance_variables.rb:83:22:83:40 | # $ hasValueFlow=22 | Missing result:hasValueFlow=22 |
|
||||
| instance_variables.rb:84:22:84:40 | # $ hasValueFlow=24 | Missing result:hasValueFlow=24 |
|
||||
| instance_variables.rb:85:22:85:40 | # $ hasValueFlow=25 | Missing result:hasValueFlow=25 |
|
||||
| instance_variables.rb:90:22:90:40 | # $ hasValueFlow=26 | Missing result:hasValueFlow=26 |
|
||||
| instance_variables.rb:91:22:91:40 | # $ hasValueFlow=26 | Missing result:hasValueFlow=26 |
|
||||
| instance_variables.rb:96:22:96:40 | # $ hasValueFlow=27 | Missing result:hasValueFlow=27 |
|
||||
| instance_variables.rb:97:23:97:41 | # $ hasValueFlow=27 | Missing result:hasValueFlow=27 |
|
||||
| instance_variables.rb:105:23:105:41 | # $ hasValueFlow=28 | Missing result:hasValueFlow=28 |
|
||||
| instance_variables.rb:109:23:109:41 | # $ hasValueFlow=28 | Missing result:hasValueFlow=28 |
|
||||
| instance_variables.rb:114:23:114:41 | # $ hasValueFlow=28 | Missing result:hasValueFlow=28 |
|
||||
| instance_variables.rb:117:23:117:41 | # $ hasValueFlow=29 | Missing result:hasValueFlow=29 |
|
||||
| instance_variables.rb:120:23:120:41 | # $ hasValueFlow=30 | Missing result:hasValueFlow=30 |
|
||||
failures
|
||||
| instance_variables.rb:55:21:55:39 | # $ hasValueFlow=42 | Missing result: hasValueFlow=42 |
|
||||
| instance_variables.rb:67:22:67:40 | # $ hasValueFlow=21 | Missing result: hasValueFlow=21 |
|
||||
| instance_variables.rb:71:18:71:36 | # $ hasValueFlow=22 | Missing result: hasValueFlow=22 |
|
||||
| instance_variables.rb:79:22:79:40 | # $ hasValueFlow=24 | Missing result: hasValueFlow=24 |
|
||||
| instance_variables.rb:83:22:83:40 | # $ hasValueFlow=22 | Missing result: hasValueFlow=22 |
|
||||
| instance_variables.rb:84:22:84:40 | # $ hasValueFlow=24 | Missing result: hasValueFlow=24 |
|
||||
| instance_variables.rb:85:22:85:40 | # $ hasValueFlow=25 | Missing result: hasValueFlow=25 |
|
||||
| instance_variables.rb:90:22:90:40 | # $ hasValueFlow=26 | Missing result: hasValueFlow=26 |
|
||||
| instance_variables.rb:91:22:91:40 | # $ hasValueFlow=26 | Missing result: hasValueFlow=26 |
|
||||
| instance_variables.rb:96:22:96:40 | # $ hasValueFlow=27 | Missing result: hasValueFlow=27 |
|
||||
| instance_variables.rb:97:23:97:41 | # $ hasValueFlow=27 | Missing result: hasValueFlow=27 |
|
||||
| instance_variables.rb:105:23:105:41 | # $ hasValueFlow=28 | Missing result: hasValueFlow=28 |
|
||||
| instance_variables.rb:109:23:109:41 | # $ hasValueFlow=28 | Missing result: hasValueFlow=28 |
|
||||
| instance_variables.rb:114:23:114:41 | # $ hasValueFlow=28 | Missing result: hasValueFlow=28 |
|
||||
| instance_variables.rb:117:23:117:41 | # $ hasValueFlow=29 | Missing result: hasValueFlow=29 |
|
||||
| instance_variables.rb:120:23:120:41 | # $ hasValueFlow=30 | Missing result: hasValueFlow=30 |
|
||||
|
||||
@@ -1 +1 @@
|
||||
import TestUtilities.InlineTypeTrackingFlowTest
|
||||
import utils.test.InlineTypeTrackingFlowTest
|
||||
|
||||
@@ -40,12 +40,16 @@ edges
|
||||
| hash_flow.rb:42:17:42:26 | call to taint | hash_flow.rb:42:5:42:8 | [post] hash [element a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | [post] hash [element 0] | hash_flow.rb:44:10:44:13 | hash [element 0] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | [post] hash [element :a] | hash_flow.rb:46:10:46:13 | hash [element :a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | [post] hash [element :a] | hash_flow.rb:48:10:48:13 | hash [element :a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | [post] hash [element a] | hash_flow.rb:46:10:46:13 | hash [element a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | [post] hash [element a] | hash_flow.rb:48:10:48:13 | hash [element a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | hash [element 0] | hash_flow.rb:43:5:43:8 | [post] hash [element 0] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | hash [element :a] | hash_flow.rb:43:5:43:8 | [post] hash [element :a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | hash [element a] | hash_flow.rb:43:5:43:8 | [post] hash [element a] | provenance | |
|
||||
| hash_flow.rb:44:10:44:13 | hash [element 0] | hash_flow.rb:44:10:44:16 | ...[...] | provenance | |
|
||||
| hash_flow.rb:46:10:46:13 | hash [element :a] | hash_flow.rb:46:10:46:17 | ...[...] | provenance | |
|
||||
| hash_flow.rb:46:10:46:13 | hash [element a] | hash_flow.rb:46:10:46:17 | ...[...] | provenance | |
|
||||
| hash_flow.rb:48:10:48:13 | hash [element :a] | hash_flow.rb:48:10:48:18 | ...[...] | provenance | |
|
||||
| hash_flow.rb:48:10:48:13 | hash [element a] | hash_flow.rb:48:10:48:18 | ...[...] | provenance | |
|
||||
| hash_flow.rb:55:5:55:9 | hash1 [element :a] | hash_flow.rb:56:10:56:14 | hash1 [element :a] | provenance | |
|
||||
| hash_flow.rb:55:13:55:37 | ...[...] [element :a] | hash_flow.rb:55:5:55:9 | hash1 [element :a] | provenance | |
|
||||
@@ -583,7 +587,9 @@ edges
|
||||
| hash_flow.rb:626:11:626:11 | a [element] | hash_flow.rb:626:11:626:16 | ...[...] | provenance | |
|
||||
| hash_flow.rb:626:11:626:16 | ...[...] | hash_flow.rb:626:10:626:17 | ( ... ) | provenance | |
|
||||
| hash_flow.rb:632:5:632:8 | hash [element :a] | hash_flow.rb:639:5:639:8 | hash [element :a] | provenance | |
|
||||
| hash_flow.rb:632:5:632:8 | hash [element :a] | hash_flow.rb:640:11:640:14 | hash [element :a] | provenance | |
|
||||
| hash_flow.rb:632:5:632:8 | hash [element :c] | hash_flow.rb:639:5:639:8 | hash [element :c] | provenance | |
|
||||
| hash_flow.rb:632:5:632:8 | hash [element :c] | hash_flow.rb:642:11:642:14 | hash [element :c] | provenance | |
|
||||
| hash_flow.rb:632:12:636:5 | call to [] [element :a] | hash_flow.rb:632:5:632:8 | hash [element :a] | provenance | |
|
||||
| hash_flow.rb:632:12:636:5 | call to [] [element :c] | hash_flow.rb:632:5:632:8 | hash [element :c] | provenance | |
|
||||
| hash_flow.rb:633:15:633:25 | call to taint | hash_flow.rb:632:12:636:5 | call to [] [element :a] | provenance | |
|
||||
@@ -599,10 +605,12 @@ edges
|
||||
| hash_flow.rb:639:5:639:8 | hash [element :a] | hash_flow.rb:639:5:639:8 | [post] hash [element] | provenance | |
|
||||
| hash_flow.rb:639:5:639:8 | hash [element :c] | hash_flow.rb:639:5:639:8 | [post] hash [element] | provenance | |
|
||||
| hash_flow.rb:639:5:639:8 | hash [element] | hash_flow.rb:639:5:639:8 | [post] hash [element] | provenance | |
|
||||
| hash_flow.rb:640:11:640:14 | hash [element :a] | hash_flow.rb:640:11:640:19 | ...[...] | provenance | |
|
||||
| hash_flow.rb:640:11:640:14 | hash [element] | hash_flow.rb:640:11:640:19 | ...[...] | provenance | |
|
||||
| hash_flow.rb:640:11:640:19 | ...[...] | hash_flow.rb:640:10:640:20 | ( ... ) | provenance | |
|
||||
| hash_flow.rb:641:11:641:14 | hash [element] | hash_flow.rb:641:11:641:19 | ...[...] | provenance | |
|
||||
| hash_flow.rb:641:11:641:19 | ...[...] | hash_flow.rb:641:10:641:20 | ( ... ) | provenance | |
|
||||
| hash_flow.rb:642:11:642:14 | hash [element :c] | hash_flow.rb:642:11:642:19 | ...[...] | provenance | |
|
||||
| hash_flow.rb:642:11:642:14 | hash [element] | hash_flow.rb:642:11:642:19 | ...[...] | provenance | |
|
||||
| hash_flow.rb:642:11:642:19 | ...[...] | hash_flow.rb:642:10:642:20 | ( ... ) | provenance | |
|
||||
| hash_flow.rb:648:5:648:8 | hash [element :a] | hash_flow.rb:653:9:653:12 | hash [element :a] | provenance | |
|
||||
@@ -1149,7 +1157,9 @@ nodes
|
||||
| hash_flow.rb:44:10:44:13 | hash [element 0] | semmle.label | hash [element 0] |
|
||||
| hash_flow.rb:44:10:44:16 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:46:10:46:13 | hash [element :a] | semmle.label | hash [element :a] |
|
||||
| hash_flow.rb:46:10:46:13 | hash [element a] | semmle.label | hash [element a] |
|
||||
| hash_flow.rb:46:10:46:17 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:48:10:48:13 | hash [element :a] | semmle.label | hash [element :a] |
|
||||
| hash_flow.rb:48:10:48:13 | hash [element a] | semmle.label | hash [element a] |
|
||||
| hash_flow.rb:48:10:48:18 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:55:5:55:9 | hash1 [element :a] | semmle.label | hash1 [element :a] |
|
||||
@@ -1740,12 +1750,14 @@ nodes
|
||||
| hash_flow.rb:639:5:639:8 | hash [element :c] | semmle.label | hash [element :c] |
|
||||
| hash_flow.rb:639:5:639:8 | hash [element] | semmle.label | hash [element] |
|
||||
| hash_flow.rb:640:10:640:20 | ( ... ) | semmle.label | ( ... ) |
|
||||
| hash_flow.rb:640:11:640:14 | hash [element :a] | semmle.label | hash [element :a] |
|
||||
| hash_flow.rb:640:11:640:14 | hash [element] | semmle.label | hash [element] |
|
||||
| hash_flow.rb:640:11:640:19 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:641:10:641:20 | ( ... ) | semmle.label | ( ... ) |
|
||||
| hash_flow.rb:641:11:641:14 | hash [element] | semmle.label | hash [element] |
|
||||
| hash_flow.rb:641:11:641:19 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:642:10:642:20 | ( ... ) | semmle.label | ( ... ) |
|
||||
| hash_flow.rb:642:11:642:14 | hash [element :c] | semmle.label | hash [element :c] |
|
||||
| hash_flow.rb:642:11:642:14 | hash [element] | semmle.label | hash [element] |
|
||||
| hash_flow.rb:642:11:642:19 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:648:5:648:8 | hash [element :a] | semmle.label | hash [element :a] |
|
||||
@@ -2349,6 +2361,8 @@ hashLiteral
|
||||
| hash_flow.rb:30:10:30:16 | ...[...] | hash_flow.rb:19:14:19:23 | call to taint | hash_flow.rb:30:10:30:16 | ...[...] | $@ | hash_flow.rb:19:14:19:23 | call to taint | call to taint |
|
||||
| hash_flow.rb:44:10:44:16 | ...[...] | hash_flow.rb:38:15:38:24 | call to taint | hash_flow.rb:44:10:44:16 | ...[...] | $@ | hash_flow.rb:38:15:38:24 | call to taint | call to taint |
|
||||
| hash_flow.rb:46:10:46:17 | ...[...] | hash_flow.rb:40:16:40:25 | call to taint | hash_flow.rb:46:10:46:17 | ...[...] | $@ | hash_flow.rb:40:16:40:25 | call to taint | call to taint |
|
||||
| hash_flow.rb:46:10:46:17 | ...[...] | hash_flow.rb:42:17:42:26 | call to taint | hash_flow.rb:46:10:46:17 | ...[...] | $@ | hash_flow.rb:42:17:42:26 | call to taint | call to taint |
|
||||
| hash_flow.rb:48:10:48:18 | ...[...] | hash_flow.rb:40:16:40:25 | call to taint | hash_flow.rb:48:10:48:18 | ...[...] | $@ | hash_flow.rb:40:16:40:25 | call to taint | call to taint |
|
||||
| hash_flow.rb:48:10:48:18 | ...[...] | hash_flow.rb:42:17:42:26 | call to taint | hash_flow.rb:48:10:48:18 | ...[...] | $@ | hash_flow.rb:42:17:42:26 | call to taint | call to taint |
|
||||
| hash_flow.rb:56:10:56:18 | ...[...] | hash_flow.rb:55:21:55:30 | call to taint | hash_flow.rb:56:10:56:18 | ...[...] | $@ | hash_flow.rb:55:21:55:30 | call to taint | call to taint |
|
||||
| hash_flow.rb:61:10:61:18 | ...[...] | hash_flow.rb:59:13:59:22 | call to taint | hash_flow.rb:61:10:61:18 | ...[...] | $@ | hash_flow.rb:59:13:59:22 | call to taint | call to taint |
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.CFG
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import ValueFlow::PathGraph
|
||||
|
||||
|
||||
@@ -43,9 +43,9 @@ def m2()
|
||||
hash['b'] = 3
|
||||
sink(hash[0]) # $ hasValueFlow=2.1
|
||||
sink(hash[1])
|
||||
sink(hash[:a]) # $ hasValueFlow=2.2
|
||||
sink(hash[:a]) # $ hasValueFlow=2.2 $ SPURIOUS hasValueFlow=2.3
|
||||
sink(hash[:b])
|
||||
sink(hash['a']) # $ hasValueFlow=2.3
|
||||
sink(hash['a']) # $ hasValueFlow=2.3 $ SPURIOUS hasValueFlow=2.2
|
||||
sink(hash['b'])
|
||||
end
|
||||
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
testFailures
|
||||
| hash_flow.rb:65:21:65:40 | # $ hasValueFlow=3.3 | Missing result:hasValueFlow=3.3 |
|
||||
| hash_flow.rb:66:21:66:49 | # $ SPURIOUS hasValueFlow=3.3 | Missing result:hasValueFlow=3.3 |
|
||||
| hash_flow.rb:65:21:65:40 | # $ hasValueFlow=3.3 | Missing result: hasValueFlow=3.3 |
|
||||
| hash_flow.rb:66:21:66:49 | # $ SPURIOUS hasValueFlow=3.3 | Missing result: hasValueFlow=3.3 |
|
||||
| hash_flow.rb:117:10:117:17 | ...[...] | Unexpected result: hasValueFlow=7.1 |
|
||||
| hash_flow.rb:119:10:119:17 | ...[...] | Unexpected result: hasValueFlow=7.1 |
|
||||
| hash_flow.rb:152:16:152:36 | # $ hasValueFlow=10.1 | Missing result:hasValueFlow=10.1 |
|
||||
| hash_flow.rb:152:16:152:36 | # $ hasValueFlow=10.1 | Missing result: hasValueFlow=10.1 |
|
||||
| hash_flow.rb:163:10:163:17 | ...[...] | Unexpected result: hasValueFlow=9.1 |
|
||||
| hash_flow.rb:187:10:187:17 | ...[...] | Unexpected result: hasValueFlow=12.1 |
|
||||
| hash_flow.rb:219:27:219:47 | # $ hasValueFlow=14.2 | Missing result:hasValueFlow=14.2 |
|
||||
| hash_flow.rb:219:27:219:47 | # $ hasValueFlow=14.2 | Missing result: hasValueFlow=14.2 |
|
||||
| hash_flow.rb:291:10:291:14 | ...[...] | Unexpected result: hasValueFlow=19.1 |
|
||||
| hash_flow.rb:294:10:294:14 | ...[...] | Unexpected result: hasValueFlow=19.3 |
|
||||
| hash_flow.rb:467:16:467:36 | # $ hasValueFlow=28.1 | Missing result:hasValueFlow=28.1 |
|
||||
| hash_flow.rb:467:16:467:36 | # $ hasValueFlow=28.1 | Missing result: hasValueFlow=28.1 |
|
||||
| hash_flow.rb:515:10:515:20 | ( ... ) | Unexpected result: hasValueFlow=31.3 |
|
||||
| hash_flow.rb:559:17:559:57 | # $ hasValueFlow=34.1 $ hasValueFlow=34.2 | Missing result:hasValueFlow=34.1 |
|
||||
| hash_flow.rb:559:17:559:57 | # $ hasValueFlow=34.1 $ hasValueFlow=34.2 | Missing result:hasValueFlow=34.2 |
|
||||
| hash_flow.rb:571:18:571:38 | # $ hasValueFlow=35.1 | Missing result:hasValueFlow=35.1 |
|
||||
| hash_flow.rb:591:20:591:60 | # $ hasValueFlow=36.1 $ hasValueFlow=36.2 | Missing result:hasValueFlow=36.1 |
|
||||
| hash_flow.rb:591:20:591:60 | # $ hasValueFlow=36.1 $ hasValueFlow=36.2 | Missing result:hasValueFlow=36.2 |
|
||||
| hash_flow.rb:559:17:559:57 | # $ hasValueFlow=34.1 $ hasValueFlow=34.2 | Missing result: hasValueFlow=34.1 |
|
||||
| hash_flow.rb:559:17:559:57 | # $ hasValueFlow=34.1 $ hasValueFlow=34.2 | Missing result: hasValueFlow=34.2 |
|
||||
| hash_flow.rb:571:18:571:38 | # $ hasValueFlow=35.1 | Missing result: hasValueFlow=35.1 |
|
||||
| hash_flow.rb:591:20:591:60 | # $ hasValueFlow=36.1 $ hasValueFlow=36.2 | Missing result: hasValueFlow=36.1 |
|
||||
| hash_flow.rb:591:20:591:60 | # $ hasValueFlow=36.1 $ hasValueFlow=36.2 | Missing result: hasValueFlow=36.2 |
|
||||
| hash_flow.rb:673:10:673:19 | ( ... ) | Unexpected result: hasValueFlow=41.1 |
|
||||
| hash_flow.rb:776:10:776:14 | ...[...] | Unexpected result: hasValueFlow=46.1 |
|
||||
| hash_flow.rb:779:10:779:14 | ...[...] | Unexpected result: hasValueFlow=46.3 |
|
||||
| hash_flow.rb:781:10:781:17 | ...[...] | Unexpected result: hasValueFlow=46.1 |
|
||||
| hash_flow.rb:784:10:784:17 | ...[...] | Unexpected result: hasValueFlow=46.3 |
|
||||
failures
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
// only that type-tracking cannot follow the flow in your test. If the dataflow
|
||||
// test (`hash-flow.ql`) shows no failures, then that may be sufficient
|
||||
// (depending on your use case).
|
||||
import TestUtilities.InlineTypeTrackingFlowTest
|
||||
import utils.test.InlineTypeTrackingFlowTest
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import TaintFlow::PathGraph
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import ValueFlowTest<DefaultFlowConfig>
|
||||
import ValueFlow::PathGraph
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import ValueFlow::PathGraph
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import ValueFlow::PathGraph
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import ValueFlow::PathGraph
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import codeql.ruby.dataflow.FlowSummary
|
||||
import codeql.ruby.TaintTracking
|
||||
import codeql.ruby.dataflow.internal.FlowSummaryImpl
|
||||
import codeql.ruby.frameworks.data.ModelsAsData
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import PathGraph
|
||||
|
||||
query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c) {
|
||||
|
||||
@@ -270,11 +270,11 @@ nodes
|
||||
| params_flow.rb:205:10:205:10 | a | semmle.label | a |
|
||||
subpaths
|
||||
testFailures
|
||||
| filter_flow.rb:21:10:21:13 | @foo | Unexpected result: hasTaintFlow= |
|
||||
| filter_flow.rb:38:10:38:13 | @foo | Unexpected result: hasTaintFlow= |
|
||||
| filter_flow.rb:55:10:55:13 | @foo | Unexpected result: hasTaintFlow= |
|
||||
| filter_flow.rb:71:10:71:17 | call to bar | Unexpected result: hasTaintFlow= |
|
||||
| filter_flow.rb:87:11:87:14 | @foo | Unexpected result: hasTaintFlow= |
|
||||
| filter_flow.rb:21:10:21:13 | @foo | Unexpected result: hasTaintFlow |
|
||||
| filter_flow.rb:38:10:38:13 | @foo | Unexpected result: hasTaintFlow |
|
||||
| filter_flow.rb:55:10:55:13 | @foo | Unexpected result: hasTaintFlow |
|
||||
| filter_flow.rb:71:10:71:17 | call to bar | Unexpected result: hasTaintFlow |
|
||||
| filter_flow.rb:87:11:87:14 | @foo | Unexpected result: hasTaintFlow |
|
||||
#select
|
||||
| filter_flow.rb:21:10:21:13 | @foo | filter_flow.rb:14:12:14:17 | call to params | filter_flow.rb:21:10:21:13 | @foo | $@ | filter_flow.rb:14:12:14:17 | call to params | call to params |
|
||||
| filter_flow.rb:38:10:38:13 | @foo | filter_flow.rb:30:12:30:17 | call to params | filter_flow.rb:38:10:38:13 | @foo | $@ | filter_flow.rb:30:12:30:17 | call to params | call to params |
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import ruby
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import TaintFlow::PathGraph
|
||||
import codeql.ruby.frameworks.Rails
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import ruby
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import TaintFlow::PathGraph
|
||||
import codeql.ruby.frameworks.Rails
|
||||
|
||||
|
||||
@@ -60,45 +60,45 @@ edges
|
||||
| hash_extensions.rb:2:5:2:5 | h [element :a] | hash_extensions.rb:3:9:3:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:2:9:2:26 | call to [] [element :a] | hash_extensions.rb:2:5:2:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:2:14:2:24 | call to source | hash_extensions.rb:2:9:2:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:3:5:3:5 | x [element] | hash_extensions.rb:4:10:4:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:3:9:3:9 | h [element :a] | hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] | provenance | |
|
||||
| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] | hash_extensions.rb:3:5:3:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:4:10:4:10 | x [element] | hash_extensions.rb:4:10:4:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:10:5:10:5 | h [element :a] | hash_extensions.rb:11:9:11:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:10:9:10:26 | call to [] [element :a] | hash_extensions.rb:10:5:10:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:10:14:10:24 | call to source | hash_extensions.rb:10:9:10:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:11:5:11:5 | x [element] | hash_extensions.rb:12:10:12:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:11:9:11:9 | h [element :a] | hash_extensions.rb:11:9:11:20 | call to to_options [element] | provenance | |
|
||||
| hash_extensions.rb:11:9:11:20 | call to to_options [element] | hash_extensions.rb:11:5:11:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:12:10:12:10 | x [element] | hash_extensions.rb:12:10:12:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:18:5:18:5 | h [element :a] | hash_extensions.rb:19:9:19:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:18:9:18:26 | call to [] [element :a] | hash_extensions.rb:18:5:18:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:18:14:18:24 | call to source | hash_extensions.rb:18:9:18:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:19:5:19:5 | x [element] | hash_extensions.rb:20:10:20:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:19:9:19:9 | h [element :a] | hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] | provenance | |
|
||||
| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] | hash_extensions.rb:19:5:19:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:20:10:20:10 | x [element] | hash_extensions.rb:20:10:20:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:3:5:3:5 | x [element :a] | hash_extensions.rb:4:10:4:10 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:3:9:3:9 | h [element :a] | hash_extensions.rb:3:9:3:24 | call to stringify_keys [element :a] | provenance | |
|
||||
| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element :a] | hash_extensions.rb:3:5:3:5 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:4:10:4:10 | x [element :a] | hash_extensions.rb:4:10:4:15 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:10:5:10:5 | h [element a] | hash_extensions.rb:11:9:11:9 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:10:9:10:30 | call to [] [element a] | hash_extensions.rb:10:5:10:5 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:10:18:10:28 | call to source | hash_extensions.rb:10:9:10:30 | call to [] [element a] | provenance | |
|
||||
| hash_extensions.rb:11:5:11:5 | x [element a] | hash_extensions.rb:12:10:12:10 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:11:9:11:9 | h [element a] | hash_extensions.rb:11:9:11:20 | call to to_options [element a] | provenance | |
|
||||
| hash_extensions.rb:11:9:11:20 | call to to_options [element a] | hash_extensions.rb:11:5:11:5 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:12:10:12:10 | x [element a] | hash_extensions.rb:12:10:12:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:18:5:18:5 | h [element a] | hash_extensions.rb:19:9:19:9 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:18:9:18:30 | call to [] [element a] | hash_extensions.rb:18:5:18:5 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:18:18:18:28 | call to source | hash_extensions.rb:18:9:18:30 | call to [] [element a] | provenance | |
|
||||
| hash_extensions.rb:19:5:19:5 | x [element a] | hash_extensions.rb:20:10:20:10 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:19:9:19:9 | h [element a] | hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element a] | provenance | |
|
||||
| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element a] | hash_extensions.rb:19:5:19:5 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:20:10:20:10 | x [element a] | hash_extensions.rb:20:10:20:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:26:5:26:5 | h [element :a] | hash_extensions.rb:27:9:27:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:26:9:26:26 | call to [] [element :a] | hash_extensions.rb:26:5:26:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:26:14:26:24 | call to source | hash_extensions.rb:26:9:26:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:27:5:27:5 | x [element] | hash_extensions.rb:28:10:28:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:27:9:27:9 | h [element :a] | hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] | provenance | |
|
||||
| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] | hash_extensions.rb:27:5:27:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:28:10:28:10 | x [element] | hash_extensions.rb:28:10:28:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:34:5:34:5 | h [element :a] | hash_extensions.rb:35:9:35:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:34:9:34:26 | call to [] [element :a] | hash_extensions.rb:34:5:34:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:34:14:34:24 | call to source | hash_extensions.rb:34:9:34:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:35:5:35:5 | x [element] | hash_extensions.rb:36:10:36:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:35:9:35:9 | h [element :a] | hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] | provenance | |
|
||||
| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] | hash_extensions.rb:35:5:35:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:36:10:36:10 | x [element] | hash_extensions.rb:36:10:36:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:27:5:27:5 | x [element :a] | hash_extensions.rb:28:10:28:10 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:27:9:27:9 | h [element :a] | hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element :a] | provenance | |
|
||||
| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element :a] | hash_extensions.rb:27:5:27:5 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:28:10:28:10 | x [element :a] | hash_extensions.rb:28:10:28:15 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:34:5:34:5 | h [element a] | hash_extensions.rb:35:9:35:9 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:34:9:34:30 | call to [] [element a] | hash_extensions.rb:34:5:34:5 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:34:18:34:28 | call to source | hash_extensions.rb:34:9:34:30 | call to [] [element a] | provenance | |
|
||||
| hash_extensions.rb:35:5:35:5 | x [element a] | hash_extensions.rb:36:10:36:10 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:35:9:35:9 | h [element a] | hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element a] | provenance | |
|
||||
| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element a] | hash_extensions.rb:35:5:35:5 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:36:10:36:10 | x [element a] | hash_extensions.rb:36:10:36:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:42:5:42:5 | h [element :a] | hash_extensions.rb:43:9:43:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:42:9:42:26 | call to [] [element :a] | hash_extensions.rb:42:5:42:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:42:14:42:24 | call to source | hash_extensions.rb:42:9:42:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:43:5:43:5 | x [element] | hash_extensions.rb:44:10:44:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:43:9:43:9 | h [element :a] | hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] | provenance | |
|
||||
| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] | hash_extensions.rb:43:5:43:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:44:10:44:10 | x [element] | hash_extensions.rb:44:10:44:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:43:5:43:5 | x [element :a] | hash_extensions.rb:44:10:44:10 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:43:9:43:9 | h [element :a] | hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element :a] | provenance | |
|
||||
| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element :a] | hash_extensions.rb:43:5:43:5 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:44:10:44:10 | x [element :a] | hash_extensions.rb:44:10:44:15 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :a] | hash_extensions.rb:51:9:51:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :b] | hash_extensions.rb:51:9:51:9 | h [element :b] | provenance | |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :d] | hash_extensions.rb:51:9:51:9 | h [element :d] | provenance | |
|
||||
@@ -305,51 +305,51 @@ nodes
|
||||
| hash_extensions.rb:2:5:2:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:2:9:2:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:2:14:2:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:3:5:3:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:3:5:3:5 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:3:9:3:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] | semmle.label | call to stringify_keys [element] |
|
||||
| hash_extensions.rb:4:10:4:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:4:10:4:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:10:5:10:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:10:9:10:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:10:14:10:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:11:5:11:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:11:9:11:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:11:9:11:20 | call to to_options [element] | semmle.label | call to to_options [element] |
|
||||
| hash_extensions.rb:12:10:12:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element :a] | semmle.label | call to stringify_keys [element :a] |
|
||||
| hash_extensions.rb:4:10:4:10 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:4:10:4:15 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:10:5:10:5 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:10:9:10:30 | call to [] [element a] | semmle.label | call to [] [element a] |
|
||||
| hash_extensions.rb:10:18:10:28 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:11:5:11:5 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:11:9:11:9 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:11:9:11:20 | call to to_options [element a] | semmle.label | call to to_options [element a] |
|
||||
| hash_extensions.rb:12:10:12:10 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:12:10:12:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:18:5:18:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:18:9:18:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:18:14:18:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:19:5:19:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:19:9:19:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] | semmle.label | call to symbolize_keys [element] |
|
||||
| hash_extensions.rb:20:10:20:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:18:5:18:5 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:18:9:18:30 | call to [] [element a] | semmle.label | call to [] [element a] |
|
||||
| hash_extensions.rb:18:18:18:28 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:19:5:19:5 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:19:9:19:9 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element a] | semmle.label | call to symbolize_keys [element a] |
|
||||
| hash_extensions.rb:20:10:20:10 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:20:10:20:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:26:5:26:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:26:9:26:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:26:14:26:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:27:5:27:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:27:5:27:5 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:27:9:27:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] | semmle.label | call to deep_stringify_keys [element] |
|
||||
| hash_extensions.rb:28:10:28:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:28:10:28:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:34:5:34:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:34:9:34:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:34:14:34:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:35:5:35:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:35:9:35:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] | semmle.label | call to deep_symbolize_keys [element] |
|
||||
| hash_extensions.rb:36:10:36:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element :a] | semmle.label | call to deep_stringify_keys [element :a] |
|
||||
| hash_extensions.rb:28:10:28:10 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:28:10:28:15 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:34:5:34:5 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:34:9:34:30 | call to [] [element a] | semmle.label | call to [] [element a] |
|
||||
| hash_extensions.rb:34:18:34:28 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:35:5:35:5 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:35:9:35:9 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element a] | semmle.label | call to deep_symbolize_keys [element a] |
|
||||
| hash_extensions.rb:36:10:36:10 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:36:10:36:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:42:5:42:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:42:9:42:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:42:14:42:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:43:5:43:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:43:5:43:5 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:43:9:43:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] | semmle.label | call to with_indifferent_access [element] |
|
||||
| hash_extensions.rb:44:10:44:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:44:10:44:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element :a] | semmle.label | call to with_indifferent_access [element :a] |
|
||||
| hash_extensions.rb:44:10:44:10 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:44:10:44:15 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :b] | semmle.label | h [element :b] |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :d] | semmle.label | h [element :d] |
|
||||
@@ -516,12 +516,12 @@ testFailures
|
||||
| active_support.rb:283:8:283:17 | call to presence | active_support.rb:282:7:282:16 | call to source | active_support.rb:283:8:283:17 | call to presence | $@ | active_support.rb:282:7:282:16 | call to source | call to source |
|
||||
| active_support.rb:286:8:286:17 | call to presence | active_support.rb:285:7:285:16 | call to source | active_support.rb:286:8:286:17 | call to presence | $@ | active_support.rb:285:7:285:16 | call to source | call to source |
|
||||
| active_support.rb:291:8:291:17 | call to deep_dup | active_support.rb:290:7:290:16 | call to source | active_support.rb:291:8:291:17 | call to deep_dup | $@ | active_support.rb:290:7:290:16 | call to source | call to source |
|
||||
| hash_extensions.rb:4:10:4:14 | ...[...] | hash_extensions.rb:2:14:2:24 | call to source | hash_extensions.rb:4:10:4:14 | ...[...] | $@ | hash_extensions.rb:2:14:2:24 | call to source | call to source |
|
||||
| hash_extensions.rb:12:10:12:14 | ...[...] | hash_extensions.rb:10:14:10:24 | call to source | hash_extensions.rb:12:10:12:14 | ...[...] | $@ | hash_extensions.rb:10:14:10:24 | call to source | call to source |
|
||||
| hash_extensions.rb:20:10:20:14 | ...[...] | hash_extensions.rb:18:14:18:24 | call to source | hash_extensions.rb:20:10:20:14 | ...[...] | $@ | hash_extensions.rb:18:14:18:24 | call to source | call to source |
|
||||
| hash_extensions.rb:28:10:28:14 | ...[...] | hash_extensions.rb:26:14:26:24 | call to source | hash_extensions.rb:28:10:28:14 | ...[...] | $@ | hash_extensions.rb:26:14:26:24 | call to source | call to source |
|
||||
| hash_extensions.rb:36:10:36:14 | ...[...] | hash_extensions.rb:34:14:34:24 | call to source | hash_extensions.rb:36:10:36:14 | ...[...] | $@ | hash_extensions.rb:34:14:34:24 | call to source | call to source |
|
||||
| hash_extensions.rb:44:10:44:14 | ...[...] | hash_extensions.rb:42:14:42:24 | call to source | hash_extensions.rb:44:10:44:14 | ...[...] | $@ | hash_extensions.rb:42:14:42:24 | call to source | call to source |
|
||||
| hash_extensions.rb:4:10:4:15 | ...[...] | hash_extensions.rb:2:14:2:24 | call to source | hash_extensions.rb:4:10:4:15 | ...[...] | $@ | hash_extensions.rb:2:14:2:24 | call to source | call to source |
|
||||
| hash_extensions.rb:12:10:12:14 | ...[...] | hash_extensions.rb:10:18:10:28 | call to source | hash_extensions.rb:12:10:12:14 | ...[...] | $@ | hash_extensions.rb:10:18:10:28 | call to source | call to source |
|
||||
| hash_extensions.rb:20:10:20:14 | ...[...] | hash_extensions.rb:18:18:18:28 | call to source | hash_extensions.rb:20:10:20:14 | ...[...] | $@ | hash_extensions.rb:18:18:18:28 | call to source | call to source |
|
||||
| hash_extensions.rb:28:10:28:15 | ...[...] | hash_extensions.rb:26:14:26:24 | call to source | hash_extensions.rb:28:10:28:15 | ...[...] | $@ | hash_extensions.rb:26:14:26:24 | call to source | call to source |
|
||||
| hash_extensions.rb:36:10:36:14 | ...[...] | hash_extensions.rb:34:18:34:28 | call to source | hash_extensions.rb:36:10:36:14 | ...[...] | $@ | hash_extensions.rb:34:18:34:28 | call to source | call to source |
|
||||
| hash_extensions.rb:44:10:44:15 | ...[...] | hash_extensions.rb:42:14:42:24 | call to source | hash_extensions.rb:44:10:44:15 | ...[...] | $@ | hash_extensions.rb:42:14:42:24 | call to source | call to source |
|
||||
| hash_extensions.rb:56:10:56:14 | ...[...] | hash_extensions.rb:50:52:50:61 | call to taint | hash_extensions.rb:56:10:56:14 | ...[...] | $@ | hash_extensions.rb:50:52:50:61 | call to taint | call to taint |
|
||||
| hash_extensions.rb:58:10:58:14 | ...[...] | hash_extensions.rb:50:14:50:23 | call to taint | hash_extensions.rb:58:10:58:14 | ...[...] | $@ | hash_extensions.rb:50:14:50:23 | call to taint | call to taint |
|
||||
| hash_extensions.rb:59:10:59:14 | ...[...] | hash_extensions.rb:50:29:50:38 | call to taint | hash_extensions.rb:59:10:59:14 | ...[...] | $@ | hash_extensions.rb:50:29:50:38 | call to taint | call to taint |
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import utils.test.InlineFlowTest
|
||||
import codeql.ruby.Frameworks
|
||||
import DefaultFlowTest
|
||||
import ValueFlow::PathGraph
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
def m_stringify_keys
|
||||
h = { a: source("a") }
|
||||
x = h.stringify_keys
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
sink x["a"] # $hasValueFlow=a
|
||||
end
|
||||
|
||||
m_stringify_keys()
|
||||
|
||||
def m_to_options
|
||||
h = { a: source("a") }
|
||||
h = { "a" => source("a") }
|
||||
x = h.to_options
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
end
|
||||
@@ -15,7 +15,7 @@ end
|
||||
m_to_options()
|
||||
|
||||
def m_symbolize_keys
|
||||
h = { a: source("a") }
|
||||
h = { "a" => source("a") }
|
||||
x = h.symbolize_keys
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
end
|
||||
@@ -25,13 +25,13 @@ m_symbolize_keys()
|
||||
def m_deep_stringify_keys
|
||||
h = { a: source("a") }
|
||||
x = h.deep_stringify_keys
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
sink x["a"] # $hasValueFlow=a
|
||||
end
|
||||
|
||||
m_deep_stringify_keys()
|
||||
|
||||
def m_deep_symbolize_keys
|
||||
h = { a: source("a") }
|
||||
h = { "a" => source("a") }
|
||||
x = h.deep_symbolize_keys
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
end
|
||||
@@ -41,7 +41,7 @@ m_deep_symbolize_keys()
|
||||
def m_with_indifferent_access
|
||||
h = { a: source("a") }
|
||||
x = h.with_indifferent_access
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
sink x["a"] # $hasValueFlow=a
|
||||
end
|
||||
|
||||
m_with_indifferent_access()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user