Merge pull request #13426 from jketema/inline-3

Update inline flow tests to use parameterized module
This commit is contained in:
Jeroen Ketema
2023-06-19 17:39:29 +02:00
committed by GitHub
208 changed files with 2065 additions and 499 deletions

View File

@@ -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.

View File

@@ -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>;

View File

@@ -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"

View File

@@ -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>
}

View File

@@ -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] |

View File

@@ -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()

View File

@@ -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 | ( ... ) |

View File

@@ -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()

View File

@@ -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 |

View File

@@ -5,6 +5,7 @@
import codeql.ruby.AST
import TestUtilities.InlineFlowTest
import DefaultFlowTest
import PathGraph
private import codeql.ruby.dataflow.FlowSummary

View File

@@ -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 |

View File

@@ -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()

View File

@@ -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] |

View File

@@ -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()

View File

@@ -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 |

View File

@@ -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()

View File

@@ -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 |

View File

@@ -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()

View File

@@ -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 |

View File

@@ -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()

View File

@@ -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] |

View File

@@ -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()

View File

@@ -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

View File

@@ -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()

View File

@@ -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 |

View File

@@ -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()

View File

@@ -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= |

View File

@@ -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()

View File

@@ -1,4 +1,5 @@
failures
testFailures
edges
| mailer.rb:3:10:3:15 | call to params | mailer.rb:3:10:3:21 | ...[...] |
nodes

View File

@@ -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()

View File

@@ -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 |

View File

@@ -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()

View File

@@ -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 |

View File

@@ -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()

View File

@@ -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! |

View File

@@ -4,4 +4,5 @@
import TestUtilities.InlineFlowTest
import codeql.ruby.Frameworks
import DefaultFlowTest
import PathGraph

View File

@@ -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] |

View File

@@ -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()

View File

@@ -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" |

View File

@@ -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()