mirror of
https://github.com/github/codeql.git
synced 2025-12-24 12:46:34 +01:00
Merge pull request #13426 from jketema/inline-3
Update inline flow tests to use parameterized module
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* The `Configuration` taint flow configuration class from `codeql.ruby.security.InsecureDownloadQuery` has been deprecated. Use the `Flow` module instead.
|
||||
@@ -13,7 +13,7 @@ import InsecureDownloadCustomizations::InsecureDownload
|
||||
/**
|
||||
* A taint tracking configuration for download of sensitive file through insecure connection.
|
||||
*/
|
||||
class Configuration extends DataFlow::Configuration {
|
||||
deprecated class Configuration extends DataFlow::Configuration {
|
||||
Configuration() { this = "InsecureDownload" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowState label) {
|
||||
@@ -29,3 +29,30 @@ class Configuration extends DataFlow::Configuration {
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint tracking configuration for download of sensitive file through insecure connection.
|
||||
*/
|
||||
module Config implements DataFlow::StateConfigSig {
|
||||
class FlowState = string;
|
||||
|
||||
predicate isSource(DataFlow::Node source, DataFlow::FlowState label) {
|
||||
source.(Source).getALabel() = label
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink, DataFlow::FlowState label) {
|
||||
sink.(Sink).getALabel() = label
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node, FlowState state) { none() }
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
|
||||
) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
module Flow = DataFlow::GlobalWithState<Config>;
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.DataFlow
|
||||
import codeql.ruby.security.InsecureDownloadQuery
|
||||
import DataFlow::PathGraph
|
||||
import Flow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
from Flow::PathNode source, Flow::PathNode sink
|
||||
where Flow::flowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ of sensitive file from $@.",
|
||||
sink.getNode().(Sink).getDownloadCall(), "Download", source.getNode(), "HTTP source"
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
* Example for a test.ql:
|
||||
* ```ql
|
||||
* import TestUtilities.InlineFlowTest
|
||||
* import DefaultFlowTest
|
||||
* import PathGraph
|
||||
*
|
||||
* from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
|
||||
* where conf.hasFlowPath(source, sink)
|
||||
* from PathNode source, PathNode sink
|
||||
* where flowPath(source, sink)
|
||||
* select sink, source, sink, "$@", source, source.toString()
|
||||
* ```
|
||||
*
|
||||
@@ -20,14 +21,10 @@
|
||||
* sink(t); // $ hasTaintFlow=2
|
||||
* ```
|
||||
*
|
||||
* If you're not interested in a specific flow type, you can disable either value or taint flow expectations as follows:
|
||||
* ```ql
|
||||
* class HasFlowTest extends InlineFlowTest {
|
||||
* override DataFlow::Configuration getTaintFlowConfig() { none() }
|
||||
*
|
||||
* override DataFlow::Configuration getValueFlowConfig() { none() }
|
||||
* }
|
||||
* ```
|
||||
* If you are only interested in value flow, then instead of importing `DefaultFlowTest`, you can import
|
||||
* `ValueFlowTest<DefaultFlowConfig>`. Similarly, if you are only interested in taint flow, then instead of
|
||||
* importing `DefaultFlowTest`, you can import `TaintFlowTest<DefaultFlowConfig>`. In both cases
|
||||
* `DefaultFlowConfig` can be replaced by another implementation of `DataFlow::ConfigSig`.
|
||||
*
|
||||
* If you need more fine-grained tuning, consider implementing a test using `InlineExpectationsTest`.
|
||||
*/
|
||||
@@ -38,72 +35,62 @@ import codeql.ruby.TaintTracking
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import TestUtilities.InlineFlowTestUtil
|
||||
|
||||
class DefaultValueFlowConf extends DataFlow::Configuration {
|
||||
DefaultValueFlowConf() { this = "qltest:defaultValueFlowConf" }
|
||||
module DefaultFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { defaultSource(source) }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) { defaultSource(n) }
|
||||
predicate isSink(DataFlow::Node sink) { defaultSink(sink) }
|
||||
|
||||
override predicate isSink(DataFlow::Node n) { defaultSink(n) }
|
||||
|
||||
override int fieldFlowBranchLimit() { result = 1000 }
|
||||
int fieldFlowBranchLimit() { result = 1000 }
|
||||
}
|
||||
|
||||
class DefaultTaintFlowConf extends TaintTracking::Configuration {
|
||||
DefaultTaintFlowConf() { this = "qltest:defaultTaintFlowConf" }
|
||||
private module NoFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { none() }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) { defaultSource(n) }
|
||||
|
||||
override predicate isSink(DataFlow::Node n) { defaultSink(n) }
|
||||
|
||||
override int fieldFlowBranchLimit() { result = 1000 }
|
||||
predicate isSink(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
class InlineFlowTest extends InlineExpectationsTest {
|
||||
InlineFlowTest() { this = "HasFlowTest" }
|
||||
module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFlowConfig> {
|
||||
module ValueFlow = DataFlow::Global<ValueFlowConfig>;
|
||||
|
||||
override string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] }
|
||||
module TaintFlow = TaintTracking::Global<TaintFlowConfig>;
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasValueFlow" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink | this.getValueFlowConfig().hasFlow(src, sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
)
|
||||
or
|
||||
tag = "hasTaintFlow" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
this.getTaintFlowConfig().hasFlow(src, sink) and
|
||||
not this.getValueFlowConfig().hasFlow(src, sink)
|
||||
|
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
)
|
||||
}
|
||||
private module InlineTest implements TestSig {
|
||||
string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] }
|
||||
|
||||
DataFlow::Configuration getValueFlowConfig() { result = any(DefaultValueFlowConf config) }
|
||||
|
||||
DataFlow::Configuration getTaintFlowConfig() { result = any(DefaultTaintFlowConf config) }
|
||||
}
|
||||
|
||||
module PathGraph {
|
||||
private import DataFlow::PathGraph as PG
|
||||
|
||||
private class PathNode extends DataFlow::PathNode {
|
||||
PathNode() {
|
||||
this.getConfiguration() =
|
||||
[any(InlineFlowTest t).getValueFlowConfig(), any(InlineFlowTest t).getTaintFlowConfig()]
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasValueFlow" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink | ValueFlow::flow(src, sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
)
|
||||
or
|
||||
tag = "hasTaintFlow" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
TaintFlow::flow(src, sink) and not ValueFlow::flow(src, sink)
|
||||
|
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { PG::edges(a, b) }
|
||||
import MakeTest<InlineTest>
|
||||
import DataFlow::MergePathGraph<ValueFlow::PathNode, TaintFlow::PathNode, ValueFlow::PathGraph, TaintFlow::PathGraph>
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) { PG::nodes(n, key, val) }
|
||||
|
||||
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
|
||||
PG::subpaths(arg, par, ret, out)
|
||||
predicate flowPath(PathNode source, PathNode sink) {
|
||||
ValueFlow::flowPath(source.asPathNode1(), sink.asPathNode1()) or
|
||||
TaintFlow::flowPath(source.asPathNode2(), sink.asPathNode2())
|
||||
}
|
||||
}
|
||||
|
||||
module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>;
|
||||
|
||||
module ValueFlowTest<DataFlow::ConfigSig ValueFlowConfig> {
|
||||
import FlowTest<ValueFlowConfig, NoFlowConfig>
|
||||
}
|
||||
|
||||
module TaintFlowTest<DataFlow::ConfigSig TaintFlowConfig> {
|
||||
import FlowTest<NoFlowConfig, TaintFlowConfig>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| array_flow.rb:2:5:2:5 | a [element 0] | array_flow.rb:3:10:3:10 | a [element 0] |
|
||||
| array_flow.rb:2:5:2:5 | a [element 0] | array_flow.rb:3:10:3:10 | a [element 0] |
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from ValueFlow::PathNode source, ValueFlow::PathNode sink
|
||||
where ValueFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| call_sensitivity.rb:9:7:9:13 | call to taint | call_sensitivity.rb:9:6:9:14 | ( ... ) |
|
||||
| call_sensitivity.rb:9:7:9:13 | call to taint | call_sensitivity.rb:9:6:9:14 | ( ... ) |
|
||||
|
||||
@@ -5,13 +5,14 @@
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.DataFlow
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DataFlow::PathGraph
|
||||
import DefaultFlowTest
|
||||
import PathGraph
|
||||
import codeql.ruby.dataflow.internal.DataFlowDispatch as DataFlowDispatch
|
||||
|
||||
query predicate mayBenefitFromCallContext = DataFlowDispatch::mayBenefitFromCallContext/2;
|
||||
|
||||
query predicate viableImplInCallContext = DataFlowDispatch::viableImplInCallContext/2;
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from TaintFlow::PathNode source, TaintFlow::PathNode sink
|
||||
where TaintFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| semantics.rb:2:5:2:5 | a | semantics.rb:3:9:3:9 | a |
|
||||
| semantics.rb:2:5:2:5 | a | semantics.rb:3:9:3:9 | a |
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import PathGraph
|
||||
private import codeql.ruby.dataflow.FlowSummary
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| captured_variables.rb:1:24:1:24 | x | captured_variables.rb:2:20:2:20 | x |
|
||||
| captured_variables.rb:1:24:1:24 | x | captured_variables.rb:2:20:2:20 | x |
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.DataFlow
|
||||
private import TestUtilities.InlineFlowTest
|
||||
import DataFlow::PathGraph
|
||||
import DefaultFlowTest
|
||||
import PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from TaintFlow::PathNode source, TaintFlow::PathNode sink
|
||||
where TaintFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| hash_flow.rb:10:5:10:8 | hash [element 0] | hash_flow.rb:30:10:30:13 | hash [element 0] |
|
||||
| hash_flow.rb:10:5:10:8 | hash [element :a] | hash_flow.rb:22:10:22:13 | hash [element :a] |
|
||||
|
||||
@@ -4,12 +4,9 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import ValueFlowTest<DefaultFlowConfig>
|
||||
import PathGraph
|
||||
|
||||
class HasFlowTest extends InlineFlowTest {
|
||||
override DataFlow::Configuration getTaintFlowConfig() { none() }
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from ValueFlow::PathNode source, ValueFlow::PathNode sink
|
||||
where ValueFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| local_dataflow.rb:78:3:78:3 | z | local_dataflow.rb:89:8:89:8 | z |
|
||||
| local_dataflow.rb:78:12:78:20 | call to source | local_dataflow.rb:79:13:79:13 | b |
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from TaintFlow::PathNode source, TaintFlow::PathNode sink
|
||||
where TaintFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| params_flow.rb:9:16:9:17 | p1 | params_flow.rb:10:10:10:11 | p1 |
|
||||
| params_flow.rb:9:20:9:21 | p2 | params_flow.rb:11:10:11:11 | p2 |
|
||||
|
||||
@@ -4,12 +4,9 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import ValueFlowTest<DefaultFlowConfig>
|
||||
import PathGraph
|
||||
|
||||
class HasFlowTest extends InlineFlowTest {
|
||||
override DataFlow::Configuration getTaintFlowConfig() { none() }
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from ValueFlow::PathNode source, ValueFlow::PathNode sink
|
||||
where ValueFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| pathname_flow.rb:4:5:4:6 | pn | pathname_flow.rb:5:10:5:11 | pn |
|
||||
| pathname_flow.rb:4:10:4:33 | call to new | pathname_flow.rb:4:5:4:6 | pn |
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from ValueFlow::PathNode source, ValueFlow::PathNode sink
|
||||
where ValueFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| ssa_flow.rb:12:9:12:9 | [post] a [element 0] | ssa_flow.rb:16:10:16:10 | a [element 0] |
|
||||
| ssa_flow.rb:12:9:12:9 | [post] a [element 0] | ssa_flow.rb:16:10:16:10 | a [element 0] |
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from ValueFlow::PathNode source, ValueFlow::PathNode sink
|
||||
where ValueFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
| string_flow.rb:85:10:85:10 | a | Unexpected result: hasValueFlow=a |
|
||||
| string_flow.rb:227:10:227:10 | a | Unexpected result: hasValueFlow=a |
|
||||
edges
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
import PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from ValueFlow::PathNode source, ValueFlow::PathNode sink
|
||||
where ValueFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| summaries.rb:1:1:1:7 | tainted | summaries.rb:2:6:2:12 | tainted |
|
||||
| summaries.rb:1:1:1:7 | tainted | summaries.rb:2:6:2:12 | tainted |
|
||||
|
||||
@@ -10,7 +10,7 @@ import codeql.ruby.dataflow.internal.FlowSummaryImpl
|
||||
import codeql.ruby.dataflow.internal.AccessPathSyntax
|
||||
import codeql.ruby.frameworks.data.ModelsAsData
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DataFlow::PathGraph
|
||||
import PathGraph
|
||||
|
||||
query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c) {
|
||||
(sc.propagatesFlowExt(s, _, _) or sc.propagatesFlowExt(_, s, _)) and
|
||||
@@ -149,22 +149,18 @@ private class SinkFromModel extends ModelInput::SinkModelCsv {
|
||||
}
|
||||
}
|
||||
|
||||
class CustomValueSink extends DefaultValueFlowConf {
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
super.isSink(sink)
|
||||
module CustomConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { DefaultFlowConfig::isSource(source) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
DefaultFlowConfig::isSink(sink)
|
||||
or
|
||||
sink = ModelOutput::getASinkNode("test-sink").asSink()
|
||||
}
|
||||
}
|
||||
|
||||
class CustomTaintSink extends DefaultTaintFlowConf {
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
super.isSink(sink)
|
||||
or
|
||||
sink = ModelOutput::getASinkNode("test-sink").asSink()
|
||||
}
|
||||
}
|
||||
import FlowTest<CustomConfig, CustomConfig>
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Configuration conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from PathNode source, PathNode sink
|
||||
where flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
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= |
|
||||
|
||||
@@ -7,12 +7,14 @@ import TestUtilities.InlineFlowTest
|
||||
import PathGraph
|
||||
import codeql.ruby.frameworks.Rails
|
||||
|
||||
class ParamsTaintFlowConf extends DefaultTaintFlowConf {
|
||||
override predicate isSource(DataFlow::Node n) {
|
||||
n.asExpr().getExpr() instanceof Rails::ParamsCall
|
||||
}
|
||||
module ParamsTaintFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node n) { n.asExpr().getExpr() instanceof Rails::ParamsCall }
|
||||
|
||||
predicate isSink(DataFlow::Node n) { DefaultFlowConfig::isSink(n) }
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, ParamsTaintFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
import FlowTest<DefaultFlowConfig, ParamsTaintFlowConfig>
|
||||
|
||||
from TaintFlow::PathNode source, TaintFlow::PathNode sink
|
||||
where TaintFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| mailer.rb:3:10:3:15 | call to params | mailer.rb:3:10:3:21 | ...[...] |
|
||||
nodes
|
||||
|
||||
@@ -7,12 +7,14 @@ import TestUtilities.InlineFlowTest
|
||||
import PathGraph
|
||||
import codeql.ruby.frameworks.Rails
|
||||
|
||||
class ParamsTaintFlowConf extends DefaultTaintFlowConf {
|
||||
override predicate isSource(DataFlow::Node n) {
|
||||
n.asExpr().getExpr() instanceof Rails::ParamsCall
|
||||
}
|
||||
module ParamsTaintFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node n) { n.asExpr().getExpr() instanceof Rails::ParamsCall }
|
||||
|
||||
predicate isSink(DataFlow::Node n) { DefaultFlowConfig::isSink(n) }
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, ParamsTaintFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
import FlowTest<DefaultFlowConfig, ParamsTaintFlowConfig>
|
||||
|
||||
from TaintFlow::PathNode source, TaintFlow::PathNode sink
|
||||
where TaintFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
| hash_extensions.rb:126:10:126:19 | call to sole | Unexpected result: hasValueFlow=b |
|
||||
edges
|
||||
| active_support.rb:10:5:10:5 | x | active_support.rb:11:10:11:10 | x |
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import codeql.ruby.Frameworks
|
||||
import DefaultFlowTest
|
||||
import PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from ValueFlow::PathNode source, ValueFlow::PathNode sink
|
||||
where ValueFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
failures
|
||||
testFailures
|
||||
#select
|
||||
| arel.rb:3:8:3:18 | call to sql | arel.rb:2:7:2:14 | call to source | arel.rb:3:8:3:18 | call to sql | $@ | arel.rb:2:7:2:14 | call to source | call to source |
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
import codeql.ruby.frameworks.Arel
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
from TaintFlow::PathNode source, TaintFlow::PathNode sink
|
||||
where TaintFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| json.rb:1:17:1:26 | call to source | json.rb:1:6:1:27 | call to parse |
|
||||
| json.rb:2:18:2:27 | call to source | json.rb:2:6:2:28 | call to parse! |
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
|
||||
import TestUtilities.InlineFlowTest
|
||||
import codeql.ruby.Frameworks
|
||||
import DefaultFlowTest
|
||||
import PathGraph
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
failures
|
||||
testFailures
|
||||
| views/index.erb:2:10:2:12 | call to foo | Unexpected result: hasTaintFlow= |
|
||||
edges
|
||||
| app.rb:75:5:75:8 | [post] self [@foo] | app.rb:76:32:76:35 | self [@foo] |
|
||||
|
||||
@@ -8,12 +8,16 @@ import PathGraph
|
||||
import codeql.ruby.frameworks.Sinatra
|
||||
import codeql.ruby.Concepts
|
||||
|
||||
class SinatraConf extends DefaultTaintFlowConf {
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
module SinatraConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source instanceof Http::Server::RequestInputAccess::Range
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { DefaultFlowConfig::isSink(sink) }
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, SinatraConf conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
import FlowTest<DefaultFlowConfig, SinatraConfig>
|
||||
|
||||
from TaintFlow::PathNode source, TaintFlow::PathNode sink
|
||||
where TaintFlow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -18,6 +18,7 @@ nodes
|
||||
| insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | semmle.label | "http://example.org/unsafe.unk..." |
|
||||
| insecure_download.rb:53:65:53:78 | "/myscript.sh" | semmle.label | "/myscript.sh" |
|
||||
subpaths
|
||||
testFailures
|
||||
#select
|
||||
| insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | $@ | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | "http://example.org/unsafe.APK" |
|
||||
| insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | $@ | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | "http://example.org/unsafe.APK" |
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.DataFlow
|
||||
import PathGraph
|
||||
import TestUtilities.InlineFlowTest
|
||||
import codeql.ruby.security.InsecureDownloadQuery
|
||||
import Flow::PathGraph
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import TestUtilities.InlineFlowTestUtil
|
||||
|
||||
class FlowTest extends InlineFlowTest {
|
||||
override DataFlow::Configuration getValueFlowConfig() { result = any(Configuration config) }
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "BAD" }
|
||||
|
||||
override DataFlow::Configuration getTaintFlowConfig() { none() }
|
||||
|
||||
override string getARelevantTag() { result = "BAD" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "BAD" and
|
||||
super.hasActualResult(location, element, "hasValueFlow", value)
|
||||
exists(DataFlow::Node src, DataFlow::Node sink | Flow::flow(src, sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, Configuration conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
from Flow::PathNode source, Flow::PathNode sink
|
||||
where Flow::flowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
Reference in New Issue
Block a user