mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Merge pull request #8533 from asgerf/mad-receiver-token
JS/Ruby: Represent non-positional arguments with Argument/Parameter tokens
This commit is contained in:
@@ -473,36 +473,6 @@ module API {
|
||||
/** Gets a data flow node that flows to the RHS of a def-node. */
|
||||
private DataFlow::LocalSourceNode defCand() { result = defCand(TypeBackTracker::end()) }
|
||||
|
||||
private Label::ApiLabel getLabelFromArgumentPosition(DataFlowDispatch::ArgumentPosition pos) {
|
||||
exists(int n |
|
||||
pos.isPositional(n) and
|
||||
result = Label::parameter(n)
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
pos.isKeyword(name) and
|
||||
result = Label::keywordParameter(name)
|
||||
)
|
||||
or
|
||||
pos.isBlock() and
|
||||
result = Label::blockParameter()
|
||||
}
|
||||
|
||||
private Label::ApiLabel getLabelFromParameterPosition(DataFlowDispatch::ParameterPosition pos) {
|
||||
exists(int n |
|
||||
pos.isPositional(n) and
|
||||
result = Label::parameter(n)
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
pos.isKeyword(name) and
|
||||
result = Label::keywordParameter(name)
|
||||
)
|
||||
or
|
||||
pos.isBlock() and
|
||||
result = Label::blockParameter()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there should be a `lbl`-edge from the given call to an argument.
|
||||
*/
|
||||
@@ -512,7 +482,7 @@ module API {
|
||||
) {
|
||||
exists(DataFlowDispatch::ArgumentPosition argPos |
|
||||
argument.sourceArgumentOf(call.asExpr(), argPos) and
|
||||
lbl = getLabelFromArgumentPosition(argPos)
|
||||
lbl = Label::getLabelFromArgumentPosition(argPos)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -525,7 +495,7 @@ module API {
|
||||
) {
|
||||
exists(DataFlowDispatch::ParameterPosition paramPos |
|
||||
paramNode.isSourceParameterOf(callable.asExpr().getExpr(), paramPos) and
|
||||
lbl = getLabelFromParameterPosition(paramPos)
|
||||
lbl = Label::getLabelFromParameterPosition(paramPos)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -803,5 +773,37 @@ module API {
|
||||
|
||||
/** Gets the label for the edge from the root node to a custom entry point of the given name. */
|
||||
LabelEntryPoint entryPoint(API::EntryPoint name) { result.getName() = name }
|
||||
|
||||
/** Gets the API graph label corresponding to the given argument position. */
|
||||
Label::ApiLabel getLabelFromArgumentPosition(DataFlowDispatch::ArgumentPosition pos) {
|
||||
exists(int n |
|
||||
pos.isPositional(n) and
|
||||
result = Label::parameter(n)
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
pos.isKeyword(name) and
|
||||
result = Label::keywordParameter(name)
|
||||
)
|
||||
or
|
||||
pos.isBlock() and
|
||||
result = Label::blockParameter()
|
||||
}
|
||||
|
||||
/** Gets the API graph label corresponding to the given parameter position. */
|
||||
Label::ApiLabel getLabelFromParameterPosition(DataFlowDispatch::ParameterPosition pos) {
|
||||
exists(int n |
|
||||
pos.isPositional(n) and
|
||||
result = Label::parameter(n)
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
pos.isKeyword(name) and
|
||||
result = Label::keywordParameter(name)
|
||||
)
|
||||
or
|
||||
pos.isBlock() and
|
||||
result = Label::blockParameter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,6 +257,8 @@ private module Cached {
|
||||
name = any(KeywordParameter kp).getName()
|
||||
or
|
||||
exists(any(Call c).getKeywordArgument(name))
|
||||
or
|
||||
FlowSummaryImplSpecific::ParsePositions::isParsedKeywordParameterPosition(_, name)
|
||||
}
|
||||
|
||||
cached
|
||||
@@ -270,7 +272,11 @@ private module Cached {
|
||||
or
|
||||
FlowSummaryImplSpecific::ParsePositions::isParsedArgumentPosition(_, pos)
|
||||
} or
|
||||
TKeywordParameterPosition(string name) { name = any(KeywordParameter kp).getName() }
|
||||
TKeywordParameterPosition(string name) {
|
||||
name = any(KeywordParameter kp).getName()
|
||||
or
|
||||
FlowSummaryImplSpecific::ParsePositions::isParsedKeywordArgumentPosition(_, name)
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
|
||||
@@ -55,17 +55,10 @@ predicate summaryElement(DataFlowCallable c, string input, string output, string
|
||||
/**
|
||||
* Gets the summary component for specification component `c`, if any.
|
||||
*
|
||||
* This covers all the Ruby-specific components of a flow summary, and
|
||||
* is currently restricted to `"BlockArgument"`.
|
||||
* This covers all the Ruby-specific components of a flow summary.
|
||||
*/
|
||||
bindingset[c]
|
||||
SummaryComponent interpretComponentSpecific(AccessPathToken c) {
|
||||
c = "Receiver" and
|
||||
result = FlowSummary::SummaryComponent::receiver()
|
||||
or
|
||||
c = "BlockArgument" and
|
||||
result = FlowSummary::SummaryComponent::block()
|
||||
or
|
||||
c = "Argument[_]" and
|
||||
result = FlowSummary::SummaryComponent::argument(any(ParameterPosition pos | pos.isPositional(_)))
|
||||
or
|
||||
@@ -83,16 +76,41 @@ SummaryComponent interpretComponentSpecific(AccessPathToken c) {
|
||||
}
|
||||
|
||||
/** Gets the textual representation of a summary component in the format used for flow summaries. */
|
||||
string getComponentSpecificCsv(SummaryComponent sc) {
|
||||
sc = TArgumentSummaryComponent(any(ParameterPosition pos | pos.isBlock())) and
|
||||
result = "BlockArgument"
|
||||
}
|
||||
string getComponentSpecificCsv(SummaryComponent sc) { none() }
|
||||
|
||||
/** Gets the textual representation of a parameter position in the format used for flow summaries. */
|
||||
string getParameterPositionCsv(ParameterPosition pos) { result = pos.toString() }
|
||||
string getParameterPositionCsv(ParameterPosition pos) {
|
||||
pos.isSelf() and result = "self"
|
||||
or
|
||||
pos.isBlock() and result = "block"
|
||||
or
|
||||
exists(int i |
|
||||
pos.isPositional(i) and
|
||||
result = i.toString()
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
pos.isKeyword(name) and
|
||||
result = name + ":"
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the textual representation of an argument position in the format used for flow summaries. */
|
||||
string getArgumentPositionCsv(ArgumentPosition pos) { result = pos.toString() }
|
||||
string getArgumentPositionCsv(ArgumentPosition pos) {
|
||||
pos.isSelf() and result = "self"
|
||||
or
|
||||
pos.isBlock() and result = "block"
|
||||
or
|
||||
exists(int i |
|
||||
pos.isPositional(i) and
|
||||
result = i.toString()
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
pos.isKeyword(name) and
|
||||
result = name + ":"
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if input specification component `c` needs a reference. */
|
||||
predicate inputNeedsReferenceSpecific(string c) { none() }
|
||||
@@ -176,6 +194,16 @@ module ParsePositions {
|
||||
isArgBody(c) and
|
||||
i = AccessPath::parseInt(c)
|
||||
}
|
||||
|
||||
predicate isParsedKeywordParameterPosition(string c, string paramName) {
|
||||
isParamBody(c) and
|
||||
c = paramName + ":"
|
||||
}
|
||||
|
||||
predicate isParsedKeywordArgumentPosition(string c, string paramName) {
|
||||
isArgBody(c) and
|
||||
c = paramName + ":"
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the argument position obtained by parsing `X` in `Parameter[X]`. */
|
||||
@@ -184,6 +212,17 @@ ArgumentPosition parseParamBody(string s) {
|
||||
ParsePositions::isParsedParameterPosition(s, i) and
|
||||
result.isPositional(i)
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
ParsePositions::isParsedKeywordParameterPosition(s, name) and
|
||||
result.isKeyword(name)
|
||||
)
|
||||
or
|
||||
s = "self" and
|
||||
result.isSelf()
|
||||
or
|
||||
s = "block" and
|
||||
result.isBlock()
|
||||
}
|
||||
|
||||
/** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */
|
||||
@@ -192,4 +231,15 @@ ParameterPosition parseArgBody(string s) {
|
||||
ParsePositions::isParsedArgumentPosition(s, i) and
|
||||
result.isPositional(i)
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
ParsePositions::isParsedKeywordArgumentPosition(s, name) and
|
||||
result.isKeyword(name)
|
||||
)
|
||||
or
|
||||
s = "self" and
|
||||
result.isSelf()
|
||||
or
|
||||
s = "block" and
|
||||
result.isBlock()
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ private class Summaries extends ModelInput::SummaryModelCsv {
|
||||
row =
|
||||
[
|
||||
"activestorage;;Member[ActiveStorage].Member[Filename].Method[new];Argument[0];ReturnValue;taint",
|
||||
"activestorage;;Member[ActiveStorage].Member[Filename].Instance.Method[sanitized];Receiver;ReturnValue;taint",
|
||||
"activestorage;;Member[ActiveStorage].Member[Filename].Instance.Method[sanitized];Argument[self];ReturnValue;taint",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,11 +61,11 @@ private class SplatSummary extends SummarizedCallable {
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
(
|
||||
// *1 = [1]
|
||||
input = "Receiver" and
|
||||
input = "Argument[self]" and
|
||||
output = "ReturnValue.ArrayElement[0]"
|
||||
or
|
||||
// *[1] = [1]
|
||||
input = "Receiver" and
|
||||
input = "Argument[self]" and
|
||||
output = "ReturnValue"
|
||||
) and
|
||||
preservesValue = true
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,7 @@ module String {
|
||||
* Taint-preserving (but not value-preserving) flow from the receiver to the return value.
|
||||
*/
|
||||
private predicate taintIdentityFlow(string input, string output, boolean preservesValue) {
|
||||
input = "Receiver" and
|
||||
input = "Argument[self]" and
|
||||
output = "ReturnValue" and
|
||||
preservesValue = false
|
||||
}
|
||||
@@ -58,7 +58,7 @@ module String {
|
||||
FormatSummary() { this = "%" }
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = ["Receiver", "Argument[0]", "Argument[0].ArrayElement"] and
|
||||
input = ["Argument[self]", "Argument[0]", "Argument[0].ArrayElement"] and
|
||||
output = "ReturnValue" and
|
||||
preservesValue = false
|
||||
}
|
||||
@@ -94,7 +94,7 @@ module String {
|
||||
CapitalizeSummary() { this = ["capitalize", "capitalize!"] }
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = "Receiver" and
|
||||
input = "Argument[self]" and
|
||||
preservesValue = false and
|
||||
output = "ReturnValue"
|
||||
}
|
||||
@@ -125,9 +125,9 @@ module String {
|
||||
taintIdentityFlow(input, output, preservesValue)
|
||||
or
|
||||
this = ["chomp!", "chop!"] and
|
||||
input = "Receiver" and
|
||||
input = "Argument[self]" and
|
||||
preservesValue = false and
|
||||
output = "Receiver"
|
||||
output = "Argument[self]"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,8 +152,8 @@ module String {
|
||||
}
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = ["Receiver", "Argument[_]"] and
|
||||
output = ["ReturnValue", "Receiver"] and
|
||||
input = ["Argument[self]", "Argument[_]"] and
|
||||
output = ["ReturnValue", "Argument[self]"] and
|
||||
preservesValue = false
|
||||
}
|
||||
}
|
||||
@@ -212,8 +212,8 @@ module String {
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
preservesValue = false and
|
||||
input = "Receiver" and
|
||||
output = ["BlockArgument.Parameter[0]", "ReturnValue"]
|
||||
input = "Argument[self]" and
|
||||
output = ["Argument[block].Parameter[0]", "ReturnValue"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ module String {
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
preservesValue = false and
|
||||
input = "Receiver" and
|
||||
input = "Argument[self]" and
|
||||
output = "ReturnValue.ArrayElement[?]"
|
||||
}
|
||||
}
|
||||
@@ -278,7 +278,7 @@ module String {
|
||||
// block return -> return value
|
||||
preservesValue = false and
|
||||
output = "ReturnValue" and
|
||||
input = ["Receiver", "Argument[1]", "BlockArgument.ReturnValue"]
|
||||
input = ["Argument[self]", "Argument[1]", "Argument[block].ReturnValue"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ module String {
|
||||
PartitionSummary() { this = ["partition", "rpartition"] }
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = "Receiver" and
|
||||
input = "Argument[self]" and
|
||||
output = "ReturnValue.ArrayElement[" + [0, 1, 2] + "]" and
|
||||
preservesValue = false
|
||||
}
|
||||
@@ -353,10 +353,10 @@ module String {
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = "Argument[0]" and
|
||||
output = ["ReturnValue", "Receiver"] and
|
||||
output = ["ReturnValue", "Argument[self]"] and
|
||||
preservesValue = false
|
||||
}
|
||||
// TODO: we should also clear any existing content in Receiver
|
||||
// TODO: we should also clear any existing content in Argument[self]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -386,7 +386,7 @@ module String {
|
||||
ScanBlockSummary() { this = "scan_with_block" and exists(mc.getBlock()) }
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = "Receiver" and
|
||||
input = "Argument[self]" and
|
||||
preservesValue = false and
|
||||
output =
|
||||
[
|
||||
@@ -394,7 +394,7 @@ module String {
|
||||
"ReturnValue",
|
||||
// scan(pattern) {|match, ...| block } -> str
|
||||
// Parameter[_] doesn't seem to work
|
||||
"BlockArgument.Parameter[" + [0 .. 10] + "]"
|
||||
"Argument[block].Parameter[" + [0 .. 10] + "]"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -404,7 +404,7 @@ module String {
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
// scan(pattern) -> array
|
||||
input = "Receiver" and
|
||||
input = "Argument[self]" and
|
||||
output = "ReturnValue.ArrayElement[?]" and
|
||||
preservesValue = false
|
||||
}
|
||||
@@ -430,12 +430,12 @@ module String {
|
||||
or
|
||||
preservesValue = false and
|
||||
(
|
||||
input = "Receiver" and
|
||||
output = "BlockArgument.Parameter[0]"
|
||||
input = "Argument[self]" and
|
||||
output = "Argument[block].Parameter[0]"
|
||||
or
|
||||
input = "Argument[0]" and output = "ReturnValue"
|
||||
or
|
||||
input = "BlockArgument.ReturnValue" and
|
||||
input = "Argument[block].ReturnValue" and
|
||||
output = "ReturnValue"
|
||||
)
|
||||
}
|
||||
@@ -471,7 +471,7 @@ module String {
|
||||
ShellSplitSummary() { this = "shellsplit" }
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = "Receiver" and
|
||||
input = "Argument[self]" and
|
||||
output = "ReturnValue.ArrayElement[?]" and
|
||||
preservesValue = false
|
||||
}
|
||||
@@ -551,11 +551,11 @@ module String {
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
taintIdentityFlow(input, output, preservesValue)
|
||||
or
|
||||
input = ["Receiver", "Argument[0]"] and
|
||||
output = "BlockArgument.Parameter[0]" and
|
||||
input = ["Argument[self]", "Argument[0]"] and
|
||||
output = "Argument[block].Parameter[0]" and
|
||||
preservesValue = false
|
||||
or
|
||||
input = "BlockArgument.ReturnValue" and
|
||||
input = "Argument[block].ReturnValue" and
|
||||
output = "ReturnValue.ArrayElement[?]" and
|
||||
preservesValue = false
|
||||
}
|
||||
@@ -571,11 +571,11 @@ module String {
|
||||
}
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = "Receiver" and
|
||||
output = "BlockArgument.Parameter[0]" and
|
||||
input = "Argument[self]" and
|
||||
output = "Argument[block].Parameter[0]" and
|
||||
preservesValue = false
|
||||
or
|
||||
input = "BlockArgument.ReturnValue" and
|
||||
input = "Argument[block].ReturnValue" and
|
||||
output = "ReturnValue.ArrayElement[?]" and
|
||||
preservesValue = false
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ class Unit = DataFlowPrivate::Unit;
|
||||
import codeql.ruby.ApiGraphs
|
||||
import codeql.ruby.dataflow.internal.AccessPathSyntax as AccessPathSyntax
|
||||
private import AccessPathSyntax
|
||||
private import codeql.ruby.dataflow.internal.FlowSummaryImplSpecific as FlowSummaryImplSpecific
|
||||
private import codeql.ruby.dataflow.internal.DataFlowDispatch as DataFlowDispatch
|
||||
|
||||
/**
|
||||
* Holds if models describing `package` may be relevant for the analysis of this database.
|
||||
@@ -107,8 +109,10 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathToken token) {
|
||||
token.getName() = "Instance" and
|
||||
result = node.getInstance()
|
||||
or
|
||||
token.getName() = "BlockArgument" and
|
||||
result = node.getBlock()
|
||||
token.getName() = "Parameter" and
|
||||
result =
|
||||
node.getASuccessor(API::Label::getLabelFromArgumentPosition(FlowSummaryImplSpecific::parseParamBody(token
|
||||
.getAnArgument())))
|
||||
// Note: The "ArrayElement" token is not implemented yet, as it ultimately requires type-tracking and
|
||||
// API graphs to be aware of the steps involving ArrayElement contributed by the standard library model.
|
||||
// Type-tracking cannot summarize function calls on its own, so it doesn't benefit from synthesized callables.
|
||||
@@ -118,7 +122,12 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathToken token) {
|
||||
* Gets a Ruby-specific API graph successor of `node` reachable by resolving `token`.
|
||||
*/
|
||||
bindingset[token]
|
||||
API::Node getExtraSuccessorFromInvoke(InvokeNode node, AccessPathToken token) { none() }
|
||||
API::Node getExtraSuccessorFromInvoke(InvokeNode node, AccessPathToken token) {
|
||||
token.getName() = "Argument" and
|
||||
result =
|
||||
node.getASuccessor(API::Label::getLabelFromParameterPosition(FlowSummaryImplSpecific::parseArgBody(token
|
||||
.getAnArgument())))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `invoke` matches the Ruby-specific call site filter in `token`.
|
||||
@@ -146,7 +155,7 @@ InvokeNode getAnInvocationOf(API::Node node) { result = node }
|
||||
*/
|
||||
bindingset[name]
|
||||
predicate isExtraValidTokenNameInIdentifyingAccessPath(string name) {
|
||||
name = ["Member", "Method", "Instance", "WithBlock", "WithoutBlock", "BlockArgument"]
|
||||
name = ["Member", "Method", "Instance", "WithBlock", "WithoutBlock"]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,7 +163,7 @@ predicate isExtraValidTokenNameInIdentifyingAccessPath(string name) {
|
||||
* in an identifying access path.
|
||||
*/
|
||||
predicate isExtraValidNoArgumentTokenInIdentifyingAccessPath(string name) {
|
||||
name = ["Instance", "WithBlock", "WithoutBlock", "BlockArgument"]
|
||||
name = ["Instance", "WithBlock", "WithoutBlock"]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,4 +174,11 @@ bindingset[name, argument]
|
||||
predicate isExtraValidTokenArgumentInIdentifyingAccessPath(string name, string argument) {
|
||||
name = ["Member", "Method"] and
|
||||
exists(argument)
|
||||
or
|
||||
name = ["Argument", "Parameter"] and
|
||||
(
|
||||
argument = ["self", "block"]
|
||||
or
|
||||
argument.regexpMatch("\\w+:") // keyword argument
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,23 +1,42 @@
|
||||
failures
|
||||
edges
|
||||
| summaries.rb:1:11:1:26 | call to identity : | summaries.rb:2:6:2:12 | tainted |
|
||||
| summaries.rb:1:11:1:26 | call to identity : | summaries.rb:4:24:4:30 | tainted : |
|
||||
| summaries.rb:1:11:1:26 | call to identity : | summaries.rb:16:36:16:42 | tainted : |
|
||||
| summaries.rb:1:11:1:26 | call to identity : | summaries.rb:20:25:20:31 | tainted : |
|
||||
| summaries.rb:1:11:1:26 | call to identity : | summaries.rb:26:31:26:37 | tainted : |
|
||||
| summaries.rb:1:11:1:26 | call to identity : | summaries.rb:30:24:30:30 | tainted : |
|
||||
| summaries.rb:1:11:1:26 | call to identity : | summaries.rb:31:27:31:33 | tainted : |
|
||||
| summaries.rb:1:11:1:26 | call to identity : | summaries.rb:34:16:34:22 | tainted |
|
||||
| summaries.rb:1:11:1:26 | call to identity : | summaries.rb:35:16:35:22 | tainted |
|
||||
| summaries.rb:1:11:1:26 | call to identity : | summaries.rb:36:21:36:27 | tainted |
|
||||
| summaries.rb:1:11:1:26 | call to identity : | summaries.rb:37:36:37:42 | tainted |
|
||||
| summaries.rb:1:20:1:26 | "taint" : | summaries.rb:1:11:1:26 | call to identity : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:2:6:2:12 | tainted |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:2:6:2:12 | tainted |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:4:24:4:30 | tainted : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:4:24:4:30 | tainted : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:16:36:16:42 | tainted : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:16:36:16:42 | tainted : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:20:25:20:31 | tainted : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:26:31:26:37 | tainted : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:30:24:30:30 | tainted : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:31:27:31:33 | tainted : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:34:16:34:22 | tainted |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:34:16:34:22 | tainted |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:35:16:35:22 | tainted |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:35:16:35:22 | tainted |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:36:21:36:27 | tainted |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:36:21:36:27 | tainted |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:37:36:37:42 | tainted |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:37:36:37:42 | tainted |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:51:24:51:30 | tainted : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:54:23:54:29 | tainted : |
|
||||
| summaries.rb:1:20:1:36 | call to source : | summaries.rb:1:11:1:36 | call to identity : |
|
||||
| summaries.rb:1:20:1:36 | call to source : | summaries.rb:1:11:1:36 | call to identity : |
|
||||
| summaries.rb:4:12:7:3 | call to apply_block : | summaries.rb:9:6:9:13 | tainted2 |
|
||||
| summaries.rb:4:12:7:3 | call to apply_block : | summaries.rb:9:6:9:13 | tainted2 |
|
||||
| summaries.rb:4:24:4:30 | tainted : | summaries.rb:4:12:7:3 | call to apply_block : |
|
||||
| summaries.rb:4:24:4:30 | tainted : | summaries.rb:4:12:7:3 | call to apply_block : |
|
||||
| summaries.rb:4:24:4:30 | tainted : | summaries.rb:4:36:4:36 | x : |
|
||||
| summaries.rb:4:24:4:30 | tainted : | summaries.rb:4:36:4:36 | x : |
|
||||
| summaries.rb:4:36:4:36 | x : | summaries.rb:5:8:5:8 | x |
|
||||
| summaries.rb:4:36:4:36 | x : | summaries.rb:5:8:5:8 | x |
|
||||
| summaries.rb:11:17:11:17 | x : | summaries.rb:12:8:12:8 | x |
|
||||
| summaries.rb:11:17:11:17 | x : | summaries.rb:12:8:12:8 | x |
|
||||
| summaries.rb:16:12:16:43 | call to apply_lambda : | summaries.rb:18:6:18:13 | tainted3 |
|
||||
| summaries.rb:16:12:16:43 | call to apply_lambda : | summaries.rb:18:6:18:13 | tainted3 |
|
||||
| summaries.rb:16:36:16:42 | tainted : | summaries.rb:11:17:11:17 | x : |
|
||||
| summaries.rb:16:36:16:42 | tainted : | summaries.rb:11:17:11:17 | x : |
|
||||
| summaries.rb:16:36:16:42 | tainted : | summaries.rb:16:12:16:43 | call to apply_lambda : |
|
||||
| summaries.rb:16:36:16:42 | tainted : | summaries.rb:16:12:16:43 | call to apply_lambda : |
|
||||
| summaries.rb:20:12:20:32 | call to firstArg : | summaries.rb:21:6:21:13 | tainted4 |
|
||||
| summaries.rb:20:25:20:31 | tainted : | summaries.rb:20:12:20:32 | call to firstArg : |
|
||||
@@ -25,26 +44,44 @@ edges
|
||||
| summaries.rb:26:31:26:37 | tainted : | summaries.rb:26:12:26:38 | call to secondArg : |
|
||||
| summaries.rb:30:24:30:30 | tainted : | summaries.rb:30:6:30:42 | call to onlyWithBlock |
|
||||
| summaries.rb:31:27:31:33 | tainted : | summaries.rb:31:6:31:34 | call to onlyWithoutBlock |
|
||||
| summaries.rb:40:7:40:13 | "taint" : | summaries.rb:41:24:41:24 | t : |
|
||||
| summaries.rb:40:7:40:13 | "taint" : | summaries.rb:42:24:42:24 | t : |
|
||||
| summaries.rb:40:7:40:13 | "taint" : | summaries.rb:44:8:44:8 | t : |
|
||||
| summaries.rb:40:7:40:17 | call to source : | summaries.rb:41:24:41:24 | t : |
|
||||
| summaries.rb:40:7:40:17 | call to source : | summaries.rb:42:24:42:24 | t : |
|
||||
| summaries.rb:40:7:40:17 | call to source : | summaries.rb:44:8:44:8 | t : |
|
||||
| summaries.rb:41:24:41:24 | t : | summaries.rb:41:8:41:25 | call to matchedByName |
|
||||
| summaries.rb:42:24:42:24 | t : | summaries.rb:42:8:42:25 | call to matchedByName |
|
||||
| summaries.rb:44:8:44:8 | t : | summaries.rb:44:8:44:27 | call to matchedByNameRcv |
|
||||
| summaries.rb:48:24:48:30 | "taint" : | summaries.rb:48:8:48:31 | call to preserveTaint |
|
||||
| summaries.rb:48:24:48:41 | call to source : | summaries.rb:48:8:48:42 | call to preserveTaint |
|
||||
| summaries.rb:51:24:51:30 | tainted : | summaries.rb:51:6:51:31 | call to namedArg |
|
||||
| summaries.rb:54:23:54:29 | tainted : | summaries.rb:54:40:54:40 | x : |
|
||||
| summaries.rb:54:40:54:40 | x : | summaries.rb:55:8:55:8 | x |
|
||||
| summaries.rb:62:24:62:53 | call to source : | summaries.rb:62:8:62:54 | call to preserveTaint |
|
||||
| summaries.rb:65:26:65:56 | call to source : | summaries.rb:65:8:65:57 | call to preserveTaint |
|
||||
nodes
|
||||
| summaries.rb:1:11:1:26 | call to identity : | semmle.label | call to identity : |
|
||||
| summaries.rb:1:20:1:26 | "taint" : | semmle.label | "taint" : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | semmle.label | call to identity : |
|
||||
| summaries.rb:1:11:1:36 | call to identity : | semmle.label | call to identity : |
|
||||
| summaries.rb:1:20:1:36 | call to source : | semmle.label | call to source : |
|
||||
| summaries.rb:1:20:1:36 | call to source : | semmle.label | call to source : |
|
||||
| summaries.rb:2:6:2:12 | tainted | semmle.label | tainted |
|
||||
| summaries.rb:2:6:2:12 | tainted | semmle.label | tainted |
|
||||
| summaries.rb:4:12:7:3 | call to apply_block : | semmle.label | call to apply_block : |
|
||||
| summaries.rb:4:12:7:3 | call to apply_block : | semmle.label | call to apply_block : |
|
||||
| summaries.rb:4:24:4:30 | tainted : | semmle.label | tainted : |
|
||||
| summaries.rb:4:24:4:30 | tainted : | semmle.label | tainted : |
|
||||
| summaries.rb:4:36:4:36 | x : | semmle.label | x : |
|
||||
| summaries.rb:4:36:4:36 | x : | semmle.label | x : |
|
||||
| summaries.rb:5:8:5:8 | x | semmle.label | x |
|
||||
| summaries.rb:5:8:5:8 | x | semmle.label | x |
|
||||
| summaries.rb:9:6:9:13 | tainted2 | semmle.label | tainted2 |
|
||||
| summaries.rb:9:6:9:13 | tainted2 | semmle.label | tainted2 |
|
||||
| summaries.rb:11:17:11:17 | x : | semmle.label | x : |
|
||||
| summaries.rb:11:17:11:17 | x : | semmle.label | x : |
|
||||
| summaries.rb:12:8:12:8 | x | semmle.label | x |
|
||||
| summaries.rb:12:8:12:8 | x | semmle.label | x |
|
||||
| summaries.rb:16:12:16:43 | call to apply_lambda : | semmle.label | call to apply_lambda : |
|
||||
| summaries.rb:16:12:16:43 | call to apply_lambda : | semmle.label | call to apply_lambda : |
|
||||
| summaries.rb:16:36:16:42 | tainted : | semmle.label | tainted : |
|
||||
| summaries.rb:16:36:16:42 | tainted : | semmle.label | tainted : |
|
||||
| summaries.rb:18:6:18:13 | tainted3 | semmle.label | tainted3 |
|
||||
| summaries.rb:18:6:18:13 | tainted3 | semmle.label | tainted3 |
|
||||
| summaries.rb:20:12:20:32 | call to firstArg : | semmle.label | call to firstArg : |
|
||||
| summaries.rb:20:25:20:31 | tainted : | semmle.label | tainted : |
|
||||
@@ -57,39 +94,65 @@ nodes
|
||||
| summaries.rb:31:6:31:34 | call to onlyWithoutBlock | semmle.label | call to onlyWithoutBlock |
|
||||
| summaries.rb:31:27:31:33 | tainted : | semmle.label | tainted : |
|
||||
| summaries.rb:34:16:34:22 | tainted | semmle.label | tainted |
|
||||
| summaries.rb:34:16:34:22 | tainted | semmle.label | tainted |
|
||||
| summaries.rb:35:16:35:22 | tainted | semmle.label | tainted |
|
||||
| summaries.rb:35:16:35:22 | tainted | semmle.label | tainted |
|
||||
| summaries.rb:36:21:36:27 | tainted | semmle.label | tainted |
|
||||
| summaries.rb:36:21:36:27 | tainted | semmle.label | tainted |
|
||||
| summaries.rb:37:36:37:42 | tainted | semmle.label | tainted |
|
||||
| summaries.rb:40:7:40:13 | "taint" : | semmle.label | "taint" : |
|
||||
| summaries.rb:37:36:37:42 | tainted | semmle.label | tainted |
|
||||
| summaries.rb:40:7:40:17 | call to source : | semmle.label | call to source : |
|
||||
| summaries.rb:41:8:41:25 | call to matchedByName | semmle.label | call to matchedByName |
|
||||
| summaries.rb:41:24:41:24 | t : | semmle.label | t : |
|
||||
| summaries.rb:42:8:42:25 | call to matchedByName | semmle.label | call to matchedByName |
|
||||
| summaries.rb:42:24:42:24 | t : | semmle.label | t : |
|
||||
| summaries.rb:44:8:44:8 | t : | semmle.label | t : |
|
||||
| summaries.rb:44:8:44:27 | call to matchedByNameRcv | semmle.label | call to matchedByNameRcv |
|
||||
| summaries.rb:48:8:48:31 | call to preserveTaint | semmle.label | call to preserveTaint |
|
||||
| summaries.rb:48:24:48:30 | "taint" : | semmle.label | "taint" : |
|
||||
| summaries.rb:48:8:48:42 | call to preserveTaint | semmle.label | call to preserveTaint |
|
||||
| summaries.rb:48:24:48:41 | call to source : | semmle.label | call to source : |
|
||||
| summaries.rb:51:6:51:31 | call to namedArg | semmle.label | call to namedArg |
|
||||
| summaries.rb:51:24:51:30 | tainted : | semmle.label | tainted : |
|
||||
| summaries.rb:54:23:54:29 | tainted : | semmle.label | tainted : |
|
||||
| summaries.rb:54:40:54:40 | x : | semmle.label | x : |
|
||||
| summaries.rb:55:8:55:8 | x | semmle.label | x |
|
||||
| summaries.rb:62:8:62:54 | call to preserveTaint | semmle.label | call to preserveTaint |
|
||||
| summaries.rb:62:24:62:53 | call to source : | semmle.label | call to source : |
|
||||
| summaries.rb:65:8:65:57 | call to preserveTaint | semmle.label | call to preserveTaint |
|
||||
| summaries.rb:65:26:65:56 | call to source : | semmle.label | call to source : |
|
||||
subpaths
|
||||
invalidSpecComponent
|
||||
invalidOutputSpecComponent
|
||||
#select
|
||||
| summaries.rb:2:6:2:12 | tainted | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:2:6:2:12 | tainted | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:5:8:5:8 | x | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:5:8:5:8 | x | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:9:6:9:13 | tainted2 | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:9:6:9:13 | tainted2 | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:12:8:12:8 | x | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:12:8:12:8 | x | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:18:6:18:13 | tainted3 | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:18:6:18:13 | tainted3 | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:21:6:21:13 | tainted4 | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:21:6:21:13 | tainted4 | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:27:6:27:13 | tainted5 | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:27:6:27:13 | tainted5 | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:30:6:30:42 | call to onlyWithBlock | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:30:6:30:42 | call to onlyWithBlock | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:31:6:31:34 | call to onlyWithoutBlock | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:31:6:31:34 | call to onlyWithoutBlock | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:34:16:34:22 | tainted | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:34:16:34:22 | tainted | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:35:16:35:22 | tainted | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:35:16:35:22 | tainted | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:36:21:36:27 | tainted | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:36:21:36:27 | tainted | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:37:36:37:42 | tainted | summaries.rb:1:20:1:26 | "taint" : | summaries.rb:37:36:37:42 | tainted | $@ | summaries.rb:1:20:1:26 | "taint" : | "taint" : |
|
||||
| summaries.rb:41:8:41:25 | call to matchedByName | summaries.rb:40:7:40:13 | "taint" : | summaries.rb:41:8:41:25 | call to matchedByName | $@ | summaries.rb:40:7:40:13 | "taint" : | "taint" : |
|
||||
| summaries.rb:42:8:42:25 | call to matchedByName | summaries.rb:40:7:40:13 | "taint" : | summaries.rb:42:8:42:25 | call to matchedByName | $@ | summaries.rb:40:7:40:13 | "taint" : | "taint" : |
|
||||
| summaries.rb:44:8:44:27 | call to matchedByNameRcv | summaries.rb:40:7:40:13 | "taint" : | summaries.rb:44:8:44:27 | call to matchedByNameRcv | $@ | summaries.rb:40:7:40:13 | "taint" : | "taint" : |
|
||||
| summaries.rb:48:8:48:31 | call to preserveTaint | summaries.rb:48:24:48:30 | "taint" : | summaries.rb:48:8:48:31 | call to preserveTaint | $@ | summaries.rb:48:24:48:30 | "taint" : | "taint" : |
|
||||
| summaries.rb:2:6:2:12 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:2:6:2:12 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:2:6:2:12 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:2:6:2:12 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:5:8:5:8 | x | summaries.rb:1:20:1:36 | call to source : | summaries.rb:5:8:5:8 | x | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:5:8:5:8 | x | summaries.rb:1:20:1:36 | call to source : | summaries.rb:5:8:5:8 | x | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:9:6:9:13 | tainted2 | summaries.rb:1:20:1:36 | call to source : | summaries.rb:9:6:9:13 | tainted2 | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:9:6:9:13 | tainted2 | summaries.rb:1:20:1:36 | call to source : | summaries.rb:9:6:9:13 | tainted2 | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:12:8:12:8 | x | summaries.rb:1:20:1:36 | call to source : | summaries.rb:12:8:12:8 | x | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:12:8:12:8 | x | summaries.rb:1:20:1:36 | call to source : | summaries.rb:12:8:12:8 | x | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:18:6:18:13 | tainted3 | summaries.rb:1:20:1:36 | call to source : | summaries.rb:18:6:18:13 | tainted3 | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:18:6:18:13 | tainted3 | summaries.rb:1:20:1:36 | call to source : | summaries.rb:18:6:18:13 | tainted3 | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:21:6:21:13 | tainted4 | summaries.rb:1:20:1:36 | call to source : | summaries.rb:21:6:21:13 | tainted4 | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:27:6:27:13 | tainted5 | summaries.rb:1:20:1:36 | call to source : | summaries.rb:27:6:27:13 | tainted5 | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:30:6:30:42 | call to onlyWithBlock | summaries.rb:1:20:1:36 | call to source : | summaries.rb:30:6:30:42 | call to onlyWithBlock | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:31:6:31:34 | call to onlyWithoutBlock | summaries.rb:1:20:1:36 | call to source : | summaries.rb:31:6:31:34 | call to onlyWithoutBlock | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:34:16:34:22 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:34:16:34:22 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:34:16:34:22 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:34:16:34:22 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:35:16:35:22 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:35:16:35:22 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:35:16:35:22 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:35:16:35:22 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:36:21:36:27 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:36:21:36:27 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:36:21:36:27 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:36:21:36:27 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:37:36:37:42 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:37:36:37:42 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:37:36:37:42 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:37:36:37:42 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:41:8:41:25 | call to matchedByName | summaries.rb:40:7:40:17 | call to source : | summaries.rb:41:8:41:25 | call to matchedByName | $@ | summaries.rb:40:7:40:17 | call to source : | call to source : |
|
||||
| summaries.rb:42:8:42:25 | call to matchedByName | summaries.rb:40:7:40:17 | call to source : | summaries.rb:42:8:42:25 | call to matchedByName | $@ | summaries.rb:40:7:40:17 | call to source : | call to source : |
|
||||
| summaries.rb:44:8:44:27 | call to matchedByNameRcv | summaries.rb:40:7:40:17 | call to source : | summaries.rb:44:8:44:27 | call to matchedByNameRcv | $@ | summaries.rb:40:7:40:17 | call to source : | call to source : |
|
||||
| summaries.rb:48:8:48:42 | call to preserveTaint | summaries.rb:48:24:48:41 | call to source : | summaries.rb:48:8:48:42 | call to preserveTaint | $@ | summaries.rb:48:24:48:41 | call to source : | call to source : |
|
||||
| summaries.rb:51:6:51:31 | call to namedArg | summaries.rb:1:20:1:36 | call to source : | summaries.rb:51:6:51:31 | call to namedArg | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:55:8:55:8 | x | summaries.rb:1:20:1:36 | call to source : | summaries.rb:55:8:55:8 | x | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
|
||||
| summaries.rb:62:8:62:54 | call to preserveTaint | summaries.rb:62:24:62:53 | call to source : | summaries.rb:62:8:62:54 | call to preserveTaint | $@ | summaries.rb:62:24:62:53 | call to source : | call to source : |
|
||||
| summaries.rb:65:8:65:57 | call to preserveTaint | summaries.rb:65:26:65:56 | call to source : | summaries.rb:65:8:65:57 | call to preserveTaint | $@ | summaries.rb:65:26:65:56 | call to source : | call to source : |
|
||||
warning
|
||||
| CSV type row should have 5 columns but has 2: test;TooFewColumns |
|
||||
| CSV type row should have 5 columns but has 8: test;TooManyColumns;;;Member[Foo].Instance;too;many;columns |
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
|
||||
import ruby
|
||||
import codeql.ruby.dataflow.FlowSummary
|
||||
import DataFlow::PathGraph
|
||||
import codeql.ruby.TaintTracking
|
||||
import codeql.ruby.dataflow.internal.FlowSummaryImpl
|
||||
import codeql.ruby.dataflow.internal.AccessPathSyntax
|
||||
import codeql.ruby.frameworks.data.ModelsAsData
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DataFlow::PathGraph
|
||||
|
||||
query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c) {
|
||||
(sc.propagatesFlowExt(s, _, _) or sc.propagatesFlowExt(_, s, _)) and
|
||||
@@ -42,10 +43,10 @@ private class SummarizedCallableApplyBlock extends SummarizedCallable {
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = "Argument[0]" and
|
||||
output = "BlockArgument.Parameter[0]" and
|
||||
output = "Argument[block].Parameter[0]" and
|
||||
preservesValue = true
|
||||
or
|
||||
input = "BlockArgument.ReturnValue" and
|
||||
input = "Argument[block].ReturnValue" and
|
||||
output = "ReturnValue" and
|
||||
preservesValue = true
|
||||
}
|
||||
@@ -75,9 +76,14 @@ private class StepsFromModel extends ModelInput::SummaryModelCsv {
|
||||
";;Member[Foo].Method[secondArg];Argument[1];ReturnValue;taint",
|
||||
";;Member[Foo].Method[onlyWithoutBlock].WithoutBlock;Argument[0];ReturnValue;taint",
|
||||
";;Member[Foo].Method[onlyWithBlock].WithBlock;Argument[0];ReturnValue;taint",
|
||||
";;Member[Foo].Method[blockArg].BlockArgument.Parameter[0].Method[preserveTaint];Argument[0];ReturnValue;taint",
|
||||
";;Member[Foo].Method[blockArg].Argument[block].Parameter[0].Method[preserveTaint];Argument[0];ReturnValue;taint",
|
||||
";;Member[Foo].Method[namedArg];Argument[foo:];ReturnValue;taint",
|
||||
";;Member[Foo].Method[intoNamedCallback];Argument[0];Argument[foo:].Parameter[0];taint",
|
||||
";;Member[Foo].Method[intoNamedParameter];Argument[0];Argument[0].Parameter[foo:];taint",
|
||||
";;Member[Foo].Method[startInNamedCallback].Argument[foo:].Parameter[0].Method[preserveTaint];Argument[0];ReturnValue;taint",
|
||||
";;Member[Foo].Method[startInNamedParameter].Argument[0].Parameter[foo:].Method[preserveTaint];Argument[0];ReturnValue;taint",
|
||||
";any;Method[matchedByName];Argument[0];ReturnValue;taint",
|
||||
";any;Method[matchedByNameRcv];Receiver;ReturnValue;taint",
|
||||
";any;Method[matchedByNameRcv];Argument[self];ReturnValue;taint",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -112,23 +118,22 @@ private class SinkFromModel extends ModelInput::SinkModelCsv {
|
||||
override predicate row(string row) { row = "test;FooOrBar;Method[method].Argument[0];test-sink" }
|
||||
}
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "FlowSummaries" }
|
||||
|
||||
override predicate isSource(DataFlow::Node src) {
|
||||
src.asExpr().getExpr().(StringLiteral).getConstantValue().isString("taint")
|
||||
}
|
||||
|
||||
class CustomValueSink extends DefaultValueFlowConf {
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(MethodCall mc |
|
||||
mc.getMethodName() = "sink" and
|
||||
mc.getAnArgument() = sink.asExpr().getExpr()
|
||||
)
|
||||
super.isSink(sink)
|
||||
or
|
||||
sink = ModelOutput::getASinkNode("test-sink").getARhs()
|
||||
}
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, Conf conf
|
||||
class CustomTaintSink extends DefaultTaintFlowConf {
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
super.isSink(sink)
|
||||
or
|
||||
sink = ModelOutput::getASinkNode("test-sink").getARhs()
|
||||
}
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Configuration conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink, source, sink, "$@", source, source.toString()
|
||||
|
||||
@@ -1,49 +1,66 @@
|
||||
tainted = identity "taint"
|
||||
sink tainted
|
||||
tainted = identity source("tainted")
|
||||
sink tainted # $ hasValueFlow=tainted
|
||||
|
||||
tainted2 = apply_block tainted do |x|
|
||||
sink x
|
||||
sink x # $ hasValueFlow=tainted
|
||||
x
|
||||
end
|
||||
|
||||
sink tainted2
|
||||
sink tainted2 # $ hasValueFlow=tainted
|
||||
|
||||
my_lambda = -> (x) {
|
||||
sink x
|
||||
sink x # $ hasValueFlow=tainted
|
||||
x
|
||||
}
|
||||
|
||||
tainted3 = apply_lambda(my_lambda, tainted)
|
||||
|
||||
sink(tainted3)
|
||||
sink(tainted3) # $ hasValueFlow=tainted
|
||||
|
||||
tainted4 = Foo.firstArg(tainted)
|
||||
sink(tainted4)
|
||||
sink(tainted4) # $ hasTaintFlow=tainted
|
||||
|
||||
notTainted = Foo.firstArg(nil, tainted))
|
||||
sink(notTainted)
|
||||
|
||||
tainted5 = Foo.secondArg(nil, tainted)
|
||||
sink(tainted5)
|
||||
sink(tainted5) # $ hasTaintFlow=tainted
|
||||
|
||||
sink(Foo.onlyWithBlock(tainted))
|
||||
sink(Foo.onlyWithBlock(tainted) do |x| end)
|
||||
sink(Foo.onlyWithoutBlock(tainted))
|
||||
sink(Foo.onlyWithBlock(tainted) do |x| end) # $ hasTaintFlow=tainted
|
||||
sink(Foo.onlyWithoutBlock(tainted)) # $ hasTaintFlow=tainted
|
||||
sink(Foo.onlyWithoutBlock(tainted) do |x| end)
|
||||
|
||||
Foo.new.method(tainted)
|
||||
Bar.new.method(tainted)
|
||||
Bar.new.next.method(tainted)
|
||||
Bar.new.next.next.next.next.method(tainted)
|
||||
Foo.new.method(tainted) # $ hasValueFlow=tainted
|
||||
Bar.new.method(tainted) # $ hasValueFlow=tainted
|
||||
Bar.new.next.method(tainted) # $ hasValueFlow=tainted
|
||||
Bar.new.next.next.next.next.method(tainted) # $ hasValueFlow=tainted
|
||||
|
||||
def userDefinedFunction(x, y)
|
||||
t = "taint"
|
||||
sink(x.matchedByName(t))
|
||||
sink(y.matchedByName(t))
|
||||
t = source("t")
|
||||
sink(x.matchedByName(t)) # $ hasTaintFlow=t
|
||||
sink(y.matchedByName(t)) # $ hasTaintFlow=t
|
||||
sink(x.unmatchedName(t))
|
||||
sink(t.matchedByNameRcv())
|
||||
sink(t.matchedByNameRcv()) # $ hasTaintFlow=t
|
||||
end
|
||||
|
||||
Foo.blockArg do |x|
|
||||
sink(x.preserveTaint("taint"))
|
||||
sink(x.preserveTaint(source("blockArg"))) # $ hasTaintFlow=blockArg
|
||||
end
|
||||
|
||||
sink(Foo.namedArg(foo: tainted)) # $ hasTaintFlow=tainted
|
||||
sink(Foo.namedArg(tainted))
|
||||
|
||||
Foo.intoNamedCallback(tainted, foo: ->(x) {
|
||||
sink(x) # $ hasTaintFlow=tainted
|
||||
})
|
||||
Foo.intoNamedParameter(tainted, ->(foo:) {
|
||||
sink(foo) # $ MISSING: hasTaintFlow=tainted
|
||||
})
|
||||
|
||||
Foo.startInNamedCallback(foo: ->(x) {
|
||||
sink(x.preserveTaint(source("startInNamedCallback"))) # $ hasTaintFlow=startInNamedCallback
|
||||
})
|
||||
Foo.startInNamedParameter(->(foo:) {
|
||||
sink(foo.preserveTaint(source("startInNamedParameter"))) # $ hasTaintFlow=startInNamedParameter
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user