mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
revert YAML.qll and yaml sinks to previous PR, make a separate experimental query only for yaml
This commit is contained in:
@@ -10,68 +10,26 @@ private import codeql.ruby.ApiGraphs
|
||||
* A taint step related to the result of `YAML.parse` calls, or similar.
|
||||
* In the following example, this step will propagate taint from
|
||||
* `source` to `sink`:
|
||||
* this contains two seperate steps:
|
||||
*
|
||||
* ```rb
|
||||
* x = source
|
||||
* sink = YAML.parse(x)
|
||||
* ```
|
||||
* By second step
|
||||
* source is a Successor of `YAML.parse(x)`
|
||||
* which ends with `to_ruby` or an Element of `to_ruby`
|
||||
* ```ruby
|
||||
* sink source.to_ruby # Unsafe call
|
||||
* result = YAML.parse(x)
|
||||
* sink result.to_ruby # Unsafe call
|
||||
* ```
|
||||
*/
|
||||
private class YamlParseStep extends AdditionalTaintStep {
|
||||
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(API::Node yamlParserMethod |
|
||||
succ = yamlParserMethod.getReturn().asSource() and
|
||||
exists(DataFlow::CallNode yamlParserMethod |
|
||||
succ = yamlParserMethod.getAMethodCall("to_ruby") and
|
||||
(
|
||||
yamlParserMethod = yamlLibrary().getMethod(["parse", "parse_stream"]) and
|
||||
pred =
|
||||
[yamlParserMethod.getParameter(0), yamlParserMethod.getKeywordParameter("yaml")].asSink()
|
||||
yamlParserMethod = yamlNode().getAMethodCall(["parse", "parse_stream"]) and
|
||||
pred = [yamlParserMethod.getArgument(0), yamlParserMethod.getKeywordArgument("yaml")]
|
||||
or
|
||||
yamlParserMethod = yamlLibrary().getMethod("parse_file") and
|
||||
pred =
|
||||
[yamlParserMethod.getParameter(0), yamlParserMethod.getKeywordParameter("filename")]
|
||||
.asSink()
|
||||
yamlParserMethod = yamlNode().getAMethodCall("parse_file") and
|
||||
pred = [yamlParserMethod.getArgument(0), yamlParserMethod.getKeywordArgument("filename")]
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(API::Node parseSuccessors | parseSuccessors = yamlNode() |
|
||||
succ =
|
||||
[
|
||||
parseSuccessors.getMethod(["to_ruby", "transform"]).getReturn().asSource(),
|
||||
parseSuccessors.getMethod(["to_ruby", "transform"]).getReturn().getAnElement().asSource()
|
||||
] and
|
||||
pred = parseSuccessors.asSource()
|
||||
)
|
||||
or
|
||||
exists(API::Node parseSuccessors | parseSuccessors = yamlNode() |
|
||||
succ =
|
||||
[
|
||||
parseSuccessors.getMethod(_).getBlock().getParameter(_).asSource(),
|
||||
parseSuccessors.getMethod(_).getReturn().asSource()
|
||||
] and
|
||||
pred = parseSuccessors.asSource()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets A Node ends with YAML parse, parse_stream, parse_file methods
|
||||
*/
|
||||
API::Node yamlNode() {
|
||||
result = yamlLibrary().getMethod(["parse", "parse_stream", "parse_file"]).getReturn()
|
||||
or
|
||||
result = yamlNode().getMethod(_).getReturn()
|
||||
or
|
||||
result = yamlNode().getMethod(_).getBlock().getParameter(_)
|
||||
or
|
||||
result = yamlNode().getAnElement()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets A YAML module instance
|
||||
*/
|
||||
API::Node yamlLibrary() { result = API::getTopLevelMember(["YAML", "Psych"]) }
|
||||
private API::Node yamlNode() { result = API::getTopLevelMember(["YAML", "Psych"]) }
|
||||
|
||||
@@ -11,7 +11,6 @@ private import codeql.ruby.dataflow.RemoteFlowSources
|
||||
private import codeql.ruby.frameworks.ActiveJob
|
||||
private import codeql.ruby.frameworks.core.Module
|
||||
private import codeql.ruby.frameworks.core.Kernel
|
||||
private import codeql.ruby.frameworks.Yaml
|
||||
|
||||
module UnsafeDeserialization {
|
||||
/**
|
||||
@@ -83,30 +82,27 @@ module UnsafeDeserialization {
|
||||
class YamlLoadArgument extends Sink {
|
||||
YamlLoadArgument() {
|
||||
// Note: this is safe in psych/yaml >= 4.0.0.
|
||||
this = yamlLibrary().getAMethodCall("load").getArgument(0)
|
||||
this = yamlNode().getAMethodCall("load").getArgument(0)
|
||||
or
|
||||
this =
|
||||
yamlLibrary()
|
||||
.getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"])
|
||||
.getArgument(0)
|
||||
yamlNode().getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"]).getArgument(0)
|
||||
or
|
||||
this = yamlLibrary().getAMethodCall(["unsafe_load", "load_stream"]).getKeywordArgument("yaml")
|
||||
this = yamlNode().getAMethodCall(["unsafe_load", "load_stream"]).getKeywordArgument("yaml")
|
||||
or
|
||||
this = yamlLibrary().getAMethodCall("unsafe_load_file").getKeywordArgument("filename")
|
||||
this = yamlNode().getAMethodCall("unsafe_load_file").getKeywordArgument("filename")
|
||||
}
|
||||
}
|
||||
|
||||
private API::Node yamlNode() { result = API::getTopLevelMember(["YAML", "Psych"]) }
|
||||
|
||||
/**
|
||||
* An argument in a call to `YAML.parse*`, considered a sink for unsafe deserialization
|
||||
* if there is a call to `to_ruby` on the returned value of any Successor.
|
||||
* if there is a call to `to_ruby` on the returned value.
|
||||
*/
|
||||
class YamlParseArgument extends Sink {
|
||||
YamlParseArgument() {
|
||||
exists(API::Node toRubyReceiver |
|
||||
toRubyReceiver = yamlNode() and this = toRubyReceiver.asSource()
|
||||
|
|
||||
exists(toRubyReceiver.getMethod(["to_ruby", "transform"]))
|
||||
)
|
||||
this =
|
||||
yamlNode().getAMethodCall(["parse", "parse_stream", "parse_file"]).getAMethodCall("to_ruby")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Deserializing untrusted data using any method that allows the construction of
|
||||
arbitrary objects is easily exploitable and, in many cases, allows an attacker
|
||||
to execute arbitrary code.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
If deserializing an untrusted YAML document using the <code>psych</code> gem,
|
||||
prefer the <code>safe_load</code> and <code>safe_load_file</code> methods over
|
||||
<code>load</code> and <code>load_file</code>, as the former will safely
|
||||
handle untrusted data. Avoid passing untrusted data to the <code>load_stream</code>
|
||||
method. In <code>psych</code> version 4.0.0 and above, the <code>load</code> method can
|
||||
safely be used.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
The following example calls the <code>Marshal.load</code>,
|
||||
<code>JSON.load</code>, <code>YAML.load</code>, and <code>Oj.load</code> methods
|
||||
on data from an HTTP request. Since these methods are capable of deserializing
|
||||
to arbitrary objects, this is inherently unsafe.
|
||||
</p>
|
||||
<sample src="examples/UnsafeDeserializationBad.rb"/>
|
||||
|
||||
<p>
|
||||
Using <code>JSON.parse</code> and <code>YAML.safe_load</code> instead, as in the
|
||||
following example, removes the vulnerability. Similarly, calling
|
||||
<code>Oj.load</code> with any mode other than <code>:object</code> is safe, as
|
||||
is calling <code>Oj.safe_load</code>. Note that there is no safe way to deserialize
|
||||
untrusted data using <code>Marshal</code>.
|
||||
</p>
|
||||
<sample src="examples/UnsafeDeserializationGood.rb"/>
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li>
|
||||
OWASP vulnerability description:
|
||||
<a href="https://www.owasp.org/index.php/Deserialization_of_untrusted_data">deserialization of untrusted data</a>.
|
||||
</li>
|
||||
<li>
|
||||
Ruby documentation: <a href="https://docs.ruby-lang.org/en/3.0.0/doc/security_rdoc.html">guidance on deserializing objects safely</a>.
|
||||
</li>
|
||||
<li>
|
||||
Ruby documentation: <a href="https://ruby-doc.org/stdlib-3.0.2/libdoc/yaml/rdoc/YAML.html#module-YAML-label-Security">security guidance on the YAML library</a>.
|
||||
</li>
|
||||
<li>
|
||||
You can read that how unsafe yaml load methods can lead to code executions:
|
||||
<a href="https://devcraft.io/2021/01/07/universal-deserialisation-gadget-for-ruby-2-x-3-x.html">Universal Deserialisation Gadget for Ruby 2.x-3.x </a>.
|
||||
</li>
|
||||
</references>
|
||||
|
||||
</qhelp>
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @name Deserialization of user-controlled yaml data
|
||||
* @description Deserializing user-controlled yaml data may allow attackers to
|
||||
* execute arbitrary code.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 9.8
|
||||
* @precision high
|
||||
* @id rb/unsafe-unsafeyamldeserialization
|
||||
* @tags security
|
||||
* external/cwe/cwe-502
|
||||
*/
|
||||
|
||||
import ruby
|
||||
import codeql.ruby.security.UnsafeDeserializationQuery
|
||||
import UnsafeCodeConstructionFlow::PathGraph
|
||||
|
||||
from UnsafeCodeConstructionFlow::PathNode source, UnsafeCodeConstructionFlow::PathNode sink
|
||||
where UnsafeCodeConstructionFlow::flowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(),
|
||||
source.getNode().(UnsafeDeserialization::Source).describe()
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Provides a taint-tracking configuration for reasoning about unsafe deserialization.
|
||||
*
|
||||
* Note, for performance reasons: only import this file if
|
||||
* `UnsafeYamlDeserializationFlow` is needed, otherwise
|
||||
* `UnsafeYamlDeserializationCustomizations` should be imported instead.
|
||||
*/
|
||||
|
||||
private import codeql.ruby.AST
|
||||
private import codeql.ruby.DataFlow
|
||||
private import codeql.ruby.TaintTracking
|
||||
private import codeql.ruby.ApiGraphs
|
||||
import UnsafeYamlDeserializationCustomizations::UnsafeYamlDeserialization
|
||||
import Yaml
|
||||
|
||||
private module UnsafeYamlDeserializationConfig implements DataFlow::StateConfigSig {
|
||||
class FlowState = FlowState::State;
|
||||
|
||||
predicate isSource(DataFlow::Node source, FlowState state) {
|
||||
source instanceof Source and
|
||||
(state instanceof FlowState::Parse or state instanceof FlowState::Load)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink, FlowState state) {
|
||||
sink instanceof Sink and
|
||||
(state instanceof FlowState::Parse or state instanceof FlowState::Load)
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
/**
|
||||
* A taint step related to the result of `YAML.parse` calls, or similar.
|
||||
* In the following example, this step will propagate taint from
|
||||
* `source` to `sink`:
|
||||
* this contains two seperate steps:
|
||||
* ```rb
|
||||
* x = source
|
||||
* sink = YAML.parse(x)
|
||||
* ```
|
||||
* By second step
|
||||
* source is a Successor of `YAML.parse(x)`
|
||||
* which ends with `to_ruby` or an Element of `to_ruby`
|
||||
* ```ruby
|
||||
* sink source.to_ruby # Unsafe call
|
||||
* ```
|
||||
*/
|
||||
predicate isAdditionalFlowStep(
|
||||
DataFlow::Node pred, FlowState stateFrom, DataFlow::Node succ, FlowState stateTo
|
||||
) {
|
||||
(
|
||||
exists(API::Node parseSuccessors, API::Node parseMethod |
|
||||
parseMethod = yamlLibrary().getMethod(["parse", "parse_stream", "parse_file"]) and
|
||||
parseSuccessors = yamlParseNode(parseMethod)
|
||||
|
|
||||
succ = parseSuccessors.getMethod("to_ruby").getReturn().asSource() and
|
||||
pred = parseMethod.getArgument(0).asSink()
|
||||
)
|
||||
or
|
||||
exists(API::Node parseMethod |
|
||||
parseMethod = yamlLibrary().getMethod(["parse", "parse_stream", "parse_file"])
|
||||
|
|
||||
succ = parseMethod.getReturn().asSource() and
|
||||
pred = parseMethod.getArgument(0).asSink()
|
||||
)
|
||||
) and
|
||||
stateFrom instanceof FlowState::Parse and
|
||||
stateTo instanceof FlowState::Parse
|
||||
}
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStepTest(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(API::Node parseMethod |
|
||||
parseMethod = yamlLibrary().getMethod(["parse", "parse_stream", "parse_file"])
|
||||
|
|
||||
succ = parseMethod.getReturn().asSource() and
|
||||
pred = parseMethod.getArgument(0).asSink()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Taint-tracking for reasoning about unsafe deserialization.
|
||||
*/
|
||||
module UnsafeCodeConstructionFlow = TaintTracking::GlobalWithState<UnsafeYamlDeserializationConfig>;
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for reasoning about unsafe
|
||||
* deserialization, as well as extension points for adding your own.
|
||||
*/
|
||||
|
||||
private import codeql.ruby.AST
|
||||
private import codeql.ruby.ApiGraphs
|
||||
private import codeql.ruby.CFG
|
||||
private import codeql.ruby.DataFlow
|
||||
private import codeql.ruby.dataflow.RemoteFlowSources
|
||||
private import codeql.ruby.frameworks.ActiveJob
|
||||
private import codeql.ruby.frameworks.core.Module
|
||||
private import codeql.ruby.frameworks.core.Kernel
|
||||
private import Yaml
|
||||
|
||||
module UnsafeYamlDeserialization {
|
||||
/** Flow states used to distinguish whether we are using a yaml parse node or a yaml load node. */
|
||||
module FlowState {
|
||||
private newtype TState =
|
||||
TParse() or
|
||||
TLoad()
|
||||
|
||||
/** A flow state used to distinguish whether we have a middle node that use `YAML.load*` or `YAML.parse*` */
|
||||
class State extends TState {
|
||||
/**
|
||||
* Gets a string representation of this state.
|
||||
*/
|
||||
string toString() { result = this.getStringRepresentation() }
|
||||
|
||||
/**
|
||||
* Gets a canonical string representation of this state.
|
||||
*/
|
||||
string getStringRepresentation() {
|
||||
this = TParse() and result = "parse"
|
||||
or
|
||||
this = TLoad() and result = "load"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A flow state used for `YAML.parse*` methods.
|
||||
*/
|
||||
class Parse extends State, TParse { }
|
||||
|
||||
/**
|
||||
* A flow state used for `YAML.load*` methods.
|
||||
*/
|
||||
class Load extends State, TLoad { }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow source for unsafe deserialization vulnerabilities.
|
||||
*/
|
||||
abstract class Source extends DataFlow::Node {
|
||||
/** Gets a string that describes the source. */
|
||||
string describe() { result = "user-provided value" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow sink for unsafe deserialization vulnerabilities.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer for unsafe deserialization vulnerabilities.
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A source of remote user input, considered as a flow source for unsafe deserialization. */
|
||||
class RemoteFlowSourceAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
/** A read of data from `STDIN`/`ARGV`, considered as a flow source for unsafe deserialization. */
|
||||
class StdInSource extends UnsafeYamlDeserialization::Source {
|
||||
boolean stdin;
|
||||
|
||||
StdInSource() {
|
||||
this = API::getTopLevelMember(["STDIN", "ARGF"]).getAMethodCall(["gets", "read"]) and
|
||||
stdin = true
|
||||
or
|
||||
// > $stdin == STDIN
|
||||
// => true
|
||||
// but $stdin is special in that it is a global variable and not a constant. `API::getTopLevelMember` only gets constants.
|
||||
exists(DataFlow::Node dollarStdin |
|
||||
dollarStdin.asExpr().getExpr().(GlobalVariableReadAccess).getVariable().getName() = "$stdin" and
|
||||
this = dollarStdin.getALocalSource().getAMethodCall(["gets", "read"])
|
||||
) and
|
||||
stdin = true
|
||||
or
|
||||
// ARGV.
|
||||
this.asExpr().getExpr().(GlobalVariableReadAccess).getVariable().getName() = "ARGV" and
|
||||
stdin = false
|
||||
or
|
||||
this.(Kernel::KernelMethodCall).getMethodName() = ["gets", "readline", "readlines"] and
|
||||
stdin = true
|
||||
}
|
||||
|
||||
override string describe() {
|
||||
if stdin = true then result = "value from stdin" else result = "value from ARGV"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument in a call to `YAML.unsafe_*` and `YAML.load_stream` , considered a sink
|
||||
* for unsafe deserialization. The `YAML` module is an alias of `Psych` in
|
||||
* recent versions of Ruby.
|
||||
*/
|
||||
class YamlLoadArgument extends Sink {
|
||||
YamlLoadArgument() {
|
||||
// Note: this is safe in psych/yaml >= 4.0.0.
|
||||
this = yamlLibrary().getAMethodCall("load").getArgument(0)
|
||||
or
|
||||
this =
|
||||
yamlLibrary()
|
||||
.getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"])
|
||||
.getArgument(0)
|
||||
or
|
||||
this = yamlLibrary().getAMethodCall(["unsafe_load", "load_stream"]).getKeywordArgument("yaml")
|
||||
or
|
||||
this = yamlLibrary().getAMethodCall("unsafe_load_file").getKeywordArgument("filename")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument in a call to `YAML.parse*`, considered a sink for unsafe deserialization
|
||||
* if there is a call to `to_ruby` on the returned value of any Successor.
|
||||
*/
|
||||
class YamlParseArgument extends Sink {
|
||||
YamlParseArgument() {
|
||||
this =
|
||||
yamlParseNode(yamlLibrary().getMethod(["parse", "parse_stream", "parse_file"]))
|
||||
.getMethod(["to_ruby", "transform"])
|
||||
.getReturn()
|
||||
.asSource()
|
||||
}
|
||||
}
|
||||
}
|
||||
34
ruby/ql/src/experimental/cwe-502/Yaml.qll
Normal file
34
ruby/ql/src/experimental/cwe-502/Yaml.qll
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Provides modeling for the `YAML` and `Psych` libraries.
|
||||
*/
|
||||
|
||||
private import codeql.ruby.dataflow.FlowSteps
|
||||
private import codeql.ruby.DataFlow
|
||||
private import codeql.ruby.ApiGraphs
|
||||
|
||||
|
||||
/**
|
||||
* Gets A Node ends with YAML parse, parse_stream, parse_file methods
|
||||
*/
|
||||
API::Node yamlParseNode(API::Node yamlParseInstance) {
|
||||
result = yamlParseInstance
|
||||
or
|
||||
result = yamlParseNode(yamlParseInstance).getReturn()
|
||||
or
|
||||
result = yamlParseNode(yamlParseInstance).getBlock()
|
||||
or
|
||||
result = yamlParseNode(yamlParseInstance).getAnElement()
|
||||
or
|
||||
result = yamlParseNode(yamlParseInstance).getParameter(_)
|
||||
or
|
||||
result = yamlParseNode(yamlParseInstance).getMethod(_)
|
||||
or
|
||||
result = yamlParseNode(yamlParseInstance).getMember(_)
|
||||
or
|
||||
result = yamlParseNode(yamlParseInstance).getArgument(_)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets A YAML module instance
|
||||
*/
|
||||
API::Node yamlLibrary() { result = API::getTopLevelMember(["YAML", "Psych"]) }
|
||||
@@ -0,0 +1,16 @@
|
||||
require 'yaml'
|
||||
|
||||
class UserController < ActionController::Base
|
||||
def yaml_example
|
||||
object = YAML.unsafe_load params[:yaml]
|
||||
object = YAML.load_stream params[:yaml]
|
||||
parsed_yaml = Psych.parse_stream(params[:yaml])
|
||||
|
||||
# to_ruby is unsafe
|
||||
parsed_yaml.children.each do |child|
|
||||
object = child.to_ruby
|
||||
end
|
||||
object = Psych.parse(params[:yaml]).to_ruby
|
||||
# ...
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
require 'yaml'
|
||||
|
||||
class UserController < ActionController::Base
|
||||
def safe_yaml_example
|
||||
object = YAML.load params[:yaml]
|
||||
object = Psych.load_file params[:yaml]
|
||||
object = YAML.safe_load params[:yaml]
|
||||
# ...
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,75 @@
|
||||
edges
|
||||
| unicode_normalization.rb:7:5:7:17 | unicode_input | unicode_normalization.rb:8:23:8:35 | unicode_input |
|
||||
| unicode_normalization.rb:7:5:7:17 | unicode_input | unicode_normalization.rb:9:22:9:34 | unicode_input |
|
||||
| unicode_normalization.rb:7:21:7:26 | call to params | unicode_normalization.rb:7:21:7:42 | ...[...] |
|
||||
| unicode_normalization.rb:7:21:7:42 | ...[...] | unicode_normalization.rb:7:5:7:17 | unicode_input |
|
||||
| unicode_normalization.rb:15:5:15:17 | unicode_input | unicode_normalization.rb:16:27:16:39 | unicode_input |
|
||||
| unicode_normalization.rb:15:5:15:17 | unicode_input | unicode_normalization.rb:16:27:16:39 | unicode_input |
|
||||
| unicode_normalization.rb:15:21:15:26 | call to params | unicode_normalization.rb:15:21:15:42 | ...[...] |
|
||||
| unicode_normalization.rb:15:21:15:26 | call to params | unicode_normalization.rb:15:21:15:42 | ...[...] |
|
||||
| unicode_normalization.rb:15:21:15:42 | ...[...] | unicode_normalization.rb:15:5:15:17 | unicode_input |
|
||||
| unicode_normalization.rb:15:21:15:42 | ...[...] | unicode_normalization.rb:15:5:15:17 | unicode_input |
|
||||
| unicode_normalization.rb:16:5:16:23 | unicode_input_manip | unicode_normalization.rb:17:23:17:41 | unicode_input_manip |
|
||||
| unicode_normalization.rb:16:5:16:23 | unicode_input_manip | unicode_normalization.rb:18:22:18:40 | unicode_input_manip |
|
||||
| unicode_normalization.rb:16:27:16:39 | unicode_input | unicode_normalization.rb:16:27:16:59 | call to sub |
|
||||
| unicode_normalization.rb:16:27:16:39 | unicode_input | unicode_normalization.rb:16:27:16:59 | call to sub |
|
||||
| unicode_normalization.rb:16:27:16:59 | call to sub | unicode_normalization.rb:16:5:16:23 | unicode_input_manip |
|
||||
| unicode_normalization.rb:24:5:24:17 | unicode_input | unicode_normalization.rb:25:37:25:49 | unicode_input |
|
||||
| unicode_normalization.rb:24:21:24:26 | call to params | unicode_normalization.rb:24:21:24:42 | ...[...] |
|
||||
| unicode_normalization.rb:24:21:24:42 | ...[...] | unicode_normalization.rb:24:5:24:17 | unicode_input |
|
||||
| unicode_normalization.rb:25:5:25:21 | unicode_html_safe | unicode_normalization.rb:26:23:26:39 | unicode_html_safe |
|
||||
| unicode_normalization.rb:25:5:25:21 | unicode_html_safe | unicode_normalization.rb:27:22:27:38 | unicode_html_safe |
|
||||
| unicode_normalization.rb:25:25:25:50 | call to html_escape | unicode_normalization.rb:25:5:25:21 | unicode_html_safe |
|
||||
| unicode_normalization.rb:25:37:25:49 | unicode_input | unicode_normalization.rb:25:25:25:50 | call to html_escape |
|
||||
| unicode_normalization.rb:33:5:33:17 | unicode_input | unicode_normalization.rb:34:40:34:52 | unicode_input |
|
||||
| unicode_normalization.rb:33:21:33:26 | call to params | unicode_normalization.rb:33:21:33:42 | ...[...] |
|
||||
| unicode_normalization.rb:33:21:33:42 | ...[...] | unicode_normalization.rb:33:5:33:17 | unicode_input |
|
||||
| unicode_normalization.rb:34:5:34:21 | unicode_html_safe | unicode_normalization.rb:35:23:35:39 | unicode_html_safe |
|
||||
| unicode_normalization.rb:34:5:34:21 | unicode_html_safe | unicode_normalization.rb:36:22:36:38 | unicode_html_safe |
|
||||
| unicode_normalization.rb:34:25:34:53 | call to escapeHTML | unicode_normalization.rb:34:25:34:63 | call to html_safe |
|
||||
| unicode_normalization.rb:34:25:34:63 | call to html_safe | unicode_normalization.rb:34:5:34:21 | unicode_html_safe |
|
||||
| unicode_normalization.rb:34:40:34:52 | unicode_input | unicode_normalization.rb:34:25:34:53 | call to escapeHTML |
|
||||
nodes
|
||||
| unicode_normalization.rb:7:5:7:17 | unicode_input | semmle.label | unicode_input |
|
||||
| unicode_normalization.rb:7:21:7:26 | call to params | semmle.label | call to params |
|
||||
| unicode_normalization.rb:7:21:7:42 | ...[...] | semmle.label | ...[...] |
|
||||
| unicode_normalization.rb:8:23:8:35 | unicode_input | semmle.label | unicode_input |
|
||||
| unicode_normalization.rb:9:22:9:34 | unicode_input | semmle.label | unicode_input |
|
||||
| unicode_normalization.rb:15:5:15:17 | unicode_input | semmle.label | unicode_input |
|
||||
| unicode_normalization.rb:15:5:15:17 | unicode_input | semmle.label | unicode_input |
|
||||
| unicode_normalization.rb:15:21:15:26 | call to params | semmle.label | call to params |
|
||||
| unicode_normalization.rb:15:21:15:42 | ...[...] | semmle.label | ...[...] |
|
||||
| unicode_normalization.rb:15:21:15:42 | ...[...] | semmle.label | ...[...] |
|
||||
| unicode_normalization.rb:16:5:16:23 | unicode_input_manip | semmle.label | unicode_input_manip |
|
||||
| unicode_normalization.rb:16:27:16:39 | unicode_input | semmle.label | unicode_input |
|
||||
| unicode_normalization.rb:16:27:16:39 | unicode_input | semmle.label | unicode_input |
|
||||
| unicode_normalization.rb:16:27:16:59 | call to sub | semmle.label | call to sub |
|
||||
| unicode_normalization.rb:17:23:17:41 | unicode_input_manip | semmle.label | unicode_input_manip |
|
||||
| unicode_normalization.rb:18:22:18:40 | unicode_input_manip | semmle.label | unicode_input_manip |
|
||||
| unicode_normalization.rb:24:5:24:17 | unicode_input | semmle.label | unicode_input |
|
||||
| unicode_normalization.rb:24:21:24:26 | call to params | semmle.label | call to params |
|
||||
| unicode_normalization.rb:24:21:24:42 | ...[...] | semmle.label | ...[...] |
|
||||
| unicode_normalization.rb:25:5:25:21 | unicode_html_safe | semmle.label | unicode_html_safe |
|
||||
| unicode_normalization.rb:25:25:25:50 | call to html_escape | semmle.label | call to html_escape |
|
||||
| unicode_normalization.rb:25:37:25:49 | unicode_input | semmle.label | unicode_input |
|
||||
| unicode_normalization.rb:26:23:26:39 | unicode_html_safe | semmle.label | unicode_html_safe |
|
||||
| unicode_normalization.rb:27:22:27:38 | unicode_html_safe | semmle.label | unicode_html_safe |
|
||||
| unicode_normalization.rb:33:5:33:17 | unicode_input | semmle.label | unicode_input |
|
||||
| unicode_normalization.rb:33:21:33:26 | call to params | semmle.label | call to params |
|
||||
| unicode_normalization.rb:33:21:33:42 | ...[...] | semmle.label | ...[...] |
|
||||
| unicode_normalization.rb:34:5:34:21 | unicode_html_safe | semmle.label | unicode_html_safe |
|
||||
| unicode_normalization.rb:34:25:34:53 | call to escapeHTML | semmle.label | call to escapeHTML |
|
||||
| unicode_normalization.rb:34:25:34:63 | call to html_safe | semmle.label | call to html_safe |
|
||||
| unicode_normalization.rb:34:40:34:52 | unicode_input | semmle.label | unicode_input |
|
||||
| unicode_normalization.rb:35:23:35:39 | unicode_html_safe | semmle.label | unicode_html_safe |
|
||||
| unicode_normalization.rb:36:22:36:38 | unicode_html_safe | semmle.label | unicode_html_safe |
|
||||
subpaths
|
||||
#select
|
||||
| unicode_normalization.rb:8:23:8:35 | unicode_input | unicode_normalization.rb:7:21:7:26 | call to params | unicode_normalization.rb:8:23:8:35 | unicode_input | This $@ processes unsafely $@ and any logical validation in-between could be bypassed using special Unicode characters. | unicode_normalization.rb:8:23:8:35 | unicode_input | Unicode transformation (Unicode normalization) | unicode_normalization.rb:7:21:7:26 | call to params | remote user-controlled data |
|
||||
| unicode_normalization.rb:9:22:9:34 | unicode_input | unicode_normalization.rb:7:21:7:26 | call to params | unicode_normalization.rb:9:22:9:34 | unicode_input | This $@ processes unsafely $@ and any logical validation in-between could be bypassed using special Unicode characters. | unicode_normalization.rb:9:22:9:34 | unicode_input | Unicode transformation (Unicode normalization) | unicode_normalization.rb:7:21:7:26 | call to params | remote user-controlled data |
|
||||
| unicode_normalization.rb:17:23:17:41 | unicode_input_manip | unicode_normalization.rb:15:21:15:26 | call to params | unicode_normalization.rb:17:23:17:41 | unicode_input_manip | This $@ processes unsafely $@ and any logical validation in-between could be bypassed using special Unicode characters. | unicode_normalization.rb:17:23:17:41 | unicode_input_manip | Unicode transformation (Unicode normalization) | unicode_normalization.rb:15:21:15:26 | call to params | remote user-controlled data |
|
||||
| unicode_normalization.rb:18:22:18:40 | unicode_input_manip | unicode_normalization.rb:15:21:15:26 | call to params | unicode_normalization.rb:18:22:18:40 | unicode_input_manip | This $@ processes unsafely $@ and any logical validation in-between could be bypassed using special Unicode characters. | unicode_normalization.rb:18:22:18:40 | unicode_input_manip | Unicode transformation (Unicode normalization) | unicode_normalization.rb:15:21:15:26 | call to params | remote user-controlled data |
|
||||
| unicode_normalization.rb:26:23:26:39 | unicode_html_safe | unicode_normalization.rb:24:21:24:26 | call to params | unicode_normalization.rb:26:23:26:39 | unicode_html_safe | This $@ processes unsafely $@ and any logical validation in-between could be bypassed using special Unicode characters. | unicode_normalization.rb:26:23:26:39 | unicode_html_safe | Unicode transformation (Unicode normalization) | unicode_normalization.rb:24:21:24:26 | call to params | remote user-controlled data |
|
||||
| unicode_normalization.rb:27:22:27:38 | unicode_html_safe | unicode_normalization.rb:24:21:24:26 | call to params | unicode_normalization.rb:27:22:27:38 | unicode_html_safe | This $@ processes unsafely $@ and any logical validation in-between could be bypassed using special Unicode characters. | unicode_normalization.rb:27:22:27:38 | unicode_html_safe | Unicode transformation (Unicode normalization) | unicode_normalization.rb:24:21:24:26 | call to params | remote user-controlled data |
|
||||
| unicode_normalization.rb:35:23:35:39 | unicode_html_safe | unicode_normalization.rb:33:21:33:26 | call to params | unicode_normalization.rb:35:23:35:39 | unicode_html_safe | This $@ processes unsafely $@ and any logical validation in-between could be bypassed using special Unicode characters. | unicode_normalization.rb:35:23:35:39 | unicode_html_safe | Unicode transformation (Unicode normalization) | unicode_normalization.rb:33:21:33:26 | call to params | remote user-controlled data |
|
||||
| unicode_normalization.rb:36:22:36:38 | unicode_html_safe | unicode_normalization.rb:33:21:33:26 | call to params | unicode_normalization.rb:36:22:36:38 | unicode_html_safe | This $@ processes unsafely $@ and any logical validation in-between could be bypassed using special Unicode characters. | unicode_normalization.rb:36:22:36:38 | unicode_html_safe | Unicode transformation (Unicode normalization) | unicode_normalization.rb:33:21:33:26 | call to params | remote user-controlled data |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/cwe-502/UnsafeYamlDeserialization.ql
|
||||
@@ -0,0 +1,75 @@
|
||||
require "active_job"
|
||||
require "base64"
|
||||
require "json"
|
||||
require "oj"
|
||||
require "yaml"
|
||||
|
||||
class UsersController < ActionController::Base
|
||||
# BAD before psych version 4.0.0 and
|
||||
def route1
|
||||
yaml_data = params[:key]
|
||||
object = Psych.load yaml_data
|
||||
object = Psych.load_file yaml_data
|
||||
end
|
||||
|
||||
# GOOD In psych version 4.0.0 and above
|
||||
def route2
|
||||
yaml_data = params[:key]
|
||||
object = Psych.load yaml_data
|
||||
object = Psych.load_file yaml_data
|
||||
end
|
||||
|
||||
# GOOD
|
||||
def route3
|
||||
yaml_data = params[:key]
|
||||
object = Psych.parse_stream(yaml_data)
|
||||
object = Psych.parse(yaml_data)
|
||||
object = Psych.parse_file(yaml_data)
|
||||
end
|
||||
|
||||
# BAD
|
||||
def route4
|
||||
yaml_data = params[:key]
|
||||
object = Psych.unsafe_load(yaml_data)
|
||||
object = Psych.unsafe_load_file(yaml_data)
|
||||
object = Psych.load_stream(yaml_data)
|
||||
parse_output = Psych.parse_stream(yaml_data)
|
||||
object = parse_output.to_ruby
|
||||
object = Psych.parse(yaml_data).to_ruby
|
||||
object = Psych.parse_file(yaml_data).to_ruby
|
||||
parsed_yaml = Psych.parse_stream(yaml_data)
|
||||
parsed_yaml.children.each do |child|
|
||||
object = child.to_ruby
|
||||
end
|
||||
Psych.parse_stream(yaml_data) do |document|
|
||||
object = document.to_ruby
|
||||
end
|
||||
object = parsed_yaml.children.first.to_ruby
|
||||
content = parsed_yaml.children[0].children[0].children
|
||||
object = parsed_yaml.to_ruby[0]
|
||||
object = content.to_ruby[0]
|
||||
object = Psych.parse(yaml_data).children[0].to_ruby
|
||||
end
|
||||
|
||||
# GOOD
|
||||
def route5
|
||||
plist_data = params[:key]
|
||||
result = Plist.parse_xml(plist_data, marshal: false)
|
||||
end
|
||||
|
||||
def stdin
|
||||
object = YAML.load $stdin.read
|
||||
|
||||
# STDIN
|
||||
object = YAML.load STDIN.gets
|
||||
|
||||
# ARGF
|
||||
object = YAML.load ARGF.read
|
||||
|
||||
# Kernel.gets
|
||||
object = YAML.load gets
|
||||
|
||||
# Kernel.readlines
|
||||
object = YAML.load readlines
|
||||
end
|
||||
end
|
||||
@@ -44,42 +44,15 @@ edges
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:138:32:138:40 | yaml_data | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:139:37:139:45 | yaml_data | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:140:32:140:40 | yaml_data | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:141:20:141:48 | call to parse_stream | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:143:14:143:35 | call to parse | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:144:14:144:40 | call to parse_file | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:146:5:146:24 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:152:14:152:33 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:152:14:152:39 | call to first | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:153:15:153:34 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:153:15:153:46 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:153:15:153:58 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:156:14:156:44 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:156:14:156:47 | ...[...] | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:142:14:142:33 | call to to_ruby | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:143:14:143:43 | call to to_ruby | provenance | |
|
||||
| UnsafeDeserialization.rb:137:5:137:13 | yaml_data | UnsafeDeserialization.rb:144:14:144:48 | call to to_ruby | provenance | |
|
||||
| UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:137:17:137:28 | ...[...] | provenance | |
|
||||
| UnsafeDeserialization.rb:137:17:137:28 | ...[...] | UnsafeDeserialization.rb:137:5:137:13 | yaml_data | provenance | |
|
||||
| UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | UnsafeDeserialization.rb:146:5:146:24 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | UnsafeDeserialization.rb:152:14:152:33 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | UnsafeDeserialization.rb:152:14:152:39 | call to first | provenance | |
|
||||
| UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | UnsafeDeserialization.rb:153:15:153:34 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | UnsafeDeserialization.rb:153:15:153:46 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | UnsafeDeserialization.rb:153:15:153:58 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:146:5:146:24 | call to children | UnsafeDeserialization.rb:146:35:146:39 | child | provenance | |
|
||||
| UnsafeDeserialization.rb:152:14:152:33 | call to children | UnsafeDeserialization.rb:152:14:152:39 | call to first | provenance | |
|
||||
| UnsafeDeserialization.rb:153:15:153:34 | call to children | UnsafeDeserialization.rb:153:15:153:37 | ...[...] | provenance | |
|
||||
| UnsafeDeserialization.rb:153:15:153:34 | call to children | UnsafeDeserialization.rb:153:15:153:46 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:153:15:153:34 | call to children | UnsafeDeserialization.rb:153:15:153:58 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:153:15:153:37 | ...[...] | UnsafeDeserialization.rb:153:15:153:46 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:153:15:153:37 | ...[...] | UnsafeDeserialization.rb:153:15:153:58 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:153:15:153:46 | call to children | UnsafeDeserialization.rb:153:15:153:49 | ...[...] | provenance | |
|
||||
| UnsafeDeserialization.rb:153:15:153:46 | call to children | UnsafeDeserialization.rb:153:15:153:58 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:153:15:153:49 | ...[...] | UnsafeDeserialization.rb:153:15:153:58 | call to children | provenance | |
|
||||
| UnsafeDeserialization.rb:156:14:156:44 | call to children | UnsafeDeserialization.rb:156:14:156:47 | ...[...] | provenance | |
|
||||
| UnsafeDeserialization.rb:161:5:161:14 | plist_data | UnsafeDeserialization.rb:162:30:162:39 | plist_data | provenance | |
|
||||
| UnsafeDeserialization.rb:161:5:161:14 | plist_data | UnsafeDeserialization.rb:163:30:163:39 | plist_data | provenance | |
|
||||
| UnsafeDeserialization.rb:161:18:161:23 | call to params | UnsafeDeserialization.rb:161:18:161:29 | ...[...] | provenance | |
|
||||
| UnsafeDeserialization.rb:161:18:161:29 | ...[...] | UnsafeDeserialization.rb:161:5:161:14 | plist_data | provenance | |
|
||||
| UnsafeDeserialization.rb:149:5:149:14 | plist_data | UnsafeDeserialization.rb:150:30:150:39 | plist_data | provenance | |
|
||||
| UnsafeDeserialization.rb:149:5:149:14 | plist_data | UnsafeDeserialization.rb:151:30:151:39 | plist_data | provenance | |
|
||||
| UnsafeDeserialization.rb:149:18:149:23 | call to params | UnsafeDeserialization.rb:149:18:149:29 | ...[...] | provenance | |
|
||||
| UnsafeDeserialization.rb:149:18:149:29 | ...[...] | UnsafeDeserialization.rb:149:5:149:14 | plist_data | provenance | |
|
||||
nodes
|
||||
| UnsafeDeserialization.rb:11:5:11:19 | serialized_data | semmle.label | serialized_data |
|
||||
| UnsafeDeserialization.rb:11:23:11:50 | call to decode64 | semmle.label | call to decode64 |
|
||||
@@ -142,32 +115,19 @@ nodes
|
||||
| UnsafeDeserialization.rb:138:32:138:40 | yaml_data | semmle.label | yaml_data |
|
||||
| UnsafeDeserialization.rb:139:37:139:45 | yaml_data | semmle.label | yaml_data |
|
||||
| UnsafeDeserialization.rb:140:32:140:40 | yaml_data | semmle.label | yaml_data |
|
||||
| UnsafeDeserialization.rb:141:20:141:48 | call to parse_stream | semmle.label | call to parse_stream |
|
||||
| UnsafeDeserialization.rb:143:14:143:35 | call to parse | semmle.label | call to parse |
|
||||
| UnsafeDeserialization.rb:144:14:144:40 | call to parse_file | semmle.label | call to parse_file |
|
||||
| UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | semmle.label | call to parse_stream |
|
||||
| UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | semmle.label | call to parse_stream |
|
||||
| UnsafeDeserialization.rb:146:5:146:24 | call to children | semmle.label | call to children |
|
||||
| UnsafeDeserialization.rb:146:35:146:39 | child | semmle.label | child |
|
||||
| UnsafeDeserialization.rb:152:14:152:33 | call to children | semmle.label | call to children |
|
||||
| UnsafeDeserialization.rb:152:14:152:39 | call to first | semmle.label | call to first |
|
||||
| UnsafeDeserialization.rb:153:15:153:34 | call to children | semmle.label | call to children |
|
||||
| UnsafeDeserialization.rb:153:15:153:37 | ...[...] | semmle.label | ...[...] |
|
||||
| UnsafeDeserialization.rb:153:15:153:46 | call to children | semmle.label | call to children |
|
||||
| UnsafeDeserialization.rb:153:15:153:49 | ...[...] | semmle.label | ...[...] |
|
||||
| UnsafeDeserialization.rb:153:15:153:58 | call to children | semmle.label | call to children |
|
||||
| UnsafeDeserialization.rb:156:14:156:44 | call to children | semmle.label | call to children |
|
||||
| UnsafeDeserialization.rb:156:14:156:47 | ...[...] | semmle.label | ...[...] |
|
||||
| UnsafeDeserialization.rb:161:5:161:14 | plist_data | semmle.label | plist_data |
|
||||
| UnsafeDeserialization.rb:161:18:161:23 | call to params | semmle.label | call to params |
|
||||
| UnsafeDeserialization.rb:161:18:161:29 | ...[...] | semmle.label | ...[...] |
|
||||
| UnsafeDeserialization.rb:162:30:162:39 | plist_data | semmle.label | plist_data |
|
||||
| UnsafeDeserialization.rb:163:30:163:39 | plist_data | semmle.label | plist_data |
|
||||
| UnsafeDeserialization.rb:173:24:173:34 | call to read | semmle.label | call to read |
|
||||
| UnsafeDeserialization.rb:176:24:176:33 | call to gets | semmle.label | call to gets |
|
||||
| UnsafeDeserialization.rb:179:24:179:32 | call to read | semmle.label | call to read |
|
||||
| UnsafeDeserialization.rb:182:24:182:27 | call to gets | semmle.label | call to gets |
|
||||
| UnsafeDeserialization.rb:185:24:185:32 | call to readlines | semmle.label | call to readlines |
|
||||
| UnsafeDeserialization.rb:142:14:142:33 | call to to_ruby | semmle.label | call to to_ruby |
|
||||
| UnsafeDeserialization.rb:143:14:143:43 | call to to_ruby | semmle.label | call to to_ruby |
|
||||
| UnsafeDeserialization.rb:144:14:144:48 | call to to_ruby | semmle.label | call to to_ruby |
|
||||
| UnsafeDeserialization.rb:149:5:149:14 | plist_data | semmle.label | plist_data |
|
||||
| UnsafeDeserialization.rb:149:18:149:23 | call to params | semmle.label | call to params |
|
||||
| UnsafeDeserialization.rb:149:18:149:29 | ...[...] | semmle.label | ...[...] |
|
||||
| UnsafeDeserialization.rb:150:30:150:39 | plist_data | semmle.label | plist_data |
|
||||
| UnsafeDeserialization.rb:151:30:151:39 | plist_data | semmle.label | plist_data |
|
||||
| UnsafeDeserialization.rb:161:24:161:34 | call to read | semmle.label | call to read |
|
||||
| UnsafeDeserialization.rb:164:24:164:33 | call to gets | semmle.label | call to gets |
|
||||
| UnsafeDeserialization.rb:167:24:167:32 | call to read | semmle.label | call to read |
|
||||
| UnsafeDeserialization.rb:170:24:170:27 | call to gets | semmle.label | call to gets |
|
||||
| UnsafeDeserialization.rb:173:24:173:32 | call to readlines | semmle.label | call to readlines |
|
||||
subpaths
|
||||
#select
|
||||
| UnsafeDeserialization.rb:12:27:12:41 | serialized_data | UnsafeDeserialization.rb:11:39:11:44 | call to params | UnsafeDeserialization.rb:12:27:12:41 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:11:39:11:44 | call to params | user-provided value |
|
||||
@@ -187,18 +147,13 @@ subpaths
|
||||
| UnsafeDeserialization.rb:138:32:138:40 | yaml_data | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:138:32:138:40 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:139:37:139:45 | yaml_data | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:139:37:139:45 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:140:32:140:40 | yaml_data | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:140:32:140:40 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:141:20:141:48 | call to parse_stream | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:141:20:141:48 | call to parse_stream | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:143:14:143:35 | call to parse | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:143:14:143:35 | call to parse | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:144:14:144:40 | call to parse_file | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:144:14:144:40 | call to parse_file | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:145:19:145:47 | call to parse_stream | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:146:35:146:39 | child | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:146:35:146:39 | child | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:152:14:152:39 | call to first | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:152:14:152:39 | call to first | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:153:15:153:58 | call to children | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:153:15:153:58 | call to children | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:156:14:156:47 | ...[...] | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:156:14:156:47 | ...[...] | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:162:30:162:39 | plist_data | UnsafeDeserialization.rb:161:18:161:23 | call to params | UnsafeDeserialization.rb:162:30:162:39 | plist_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:161:18:161:23 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:163:30:163:39 | plist_data | UnsafeDeserialization.rb:161:18:161:23 | call to params | UnsafeDeserialization.rb:163:30:163:39 | plist_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:161:18:161:23 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:173:24:173:34 | call to read | UnsafeDeserialization.rb:173:24:173:34 | call to read | UnsafeDeserialization.rb:173:24:173:34 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:173:24:173:34 | call to read | value from stdin |
|
||||
| UnsafeDeserialization.rb:176:24:176:33 | call to gets | UnsafeDeserialization.rb:176:24:176:33 | call to gets | UnsafeDeserialization.rb:176:24:176:33 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:176:24:176:33 | call to gets | value from stdin |
|
||||
| UnsafeDeserialization.rb:179:24:179:32 | call to read | UnsafeDeserialization.rb:179:24:179:32 | call to read | UnsafeDeserialization.rb:179:24:179:32 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:179:24:179:32 | call to read | value from stdin |
|
||||
| UnsafeDeserialization.rb:182:24:182:27 | call to gets | UnsafeDeserialization.rb:182:24:182:27 | call to gets | UnsafeDeserialization.rb:182:24:182:27 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:182:24:182:27 | call to gets | value from stdin |
|
||||
| UnsafeDeserialization.rb:185:24:185:32 | call to readlines | UnsafeDeserialization.rb:185:24:185:32 | call to readlines | UnsafeDeserialization.rb:185:24:185:32 | call to readlines | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:185:24:185:32 | call to readlines | value from stdin |
|
||||
| UnsafeDeserialization.rb:142:14:142:33 | call to to_ruby | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:142:14:142:33 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:143:14:143:43 | call to to_ruby | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:143:14:143:43 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:144:14:144:48 | call to to_ruby | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:144:14:144:48 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:150:30:150:39 | plist_data | UnsafeDeserialization.rb:149:18:149:23 | call to params | UnsafeDeserialization.rb:150:30:150:39 | plist_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:149:18:149:23 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:151:30:151:39 | plist_data | UnsafeDeserialization.rb:149:18:149:23 | call to params | UnsafeDeserialization.rb:151:30:151:39 | plist_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:149:18:149:23 | call to params | user-provided value |
|
||||
| UnsafeDeserialization.rb:161:24:161:34 | call to read | UnsafeDeserialization.rb:161:24:161:34 | call to read | UnsafeDeserialization.rb:161:24:161:34 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:161:24:161:34 | call to read | value from stdin |
|
||||
| UnsafeDeserialization.rb:164:24:164:33 | call to gets | UnsafeDeserialization.rb:164:24:164:33 | call to gets | UnsafeDeserialization.rb:164:24:164:33 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:164:24:164:33 | call to gets | value from stdin |
|
||||
| UnsafeDeserialization.rb:167:24:167:32 | call to read | UnsafeDeserialization.rb:167:24:167:32 | call to read | UnsafeDeserialization.rb:167:24:167:32 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:167:24:167:32 | call to read | value from stdin |
|
||||
| UnsafeDeserialization.rb:170:24:170:27 | call to gets | UnsafeDeserialization.rb:170:24:170:27 | call to gets | UnsafeDeserialization.rb:170:24:170:27 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:170:24:170:27 | call to gets | value from stdin |
|
||||
| UnsafeDeserialization.rb:173:24:173:32 | call to readlines | UnsafeDeserialization.rb:173:24:173:32 | call to readlines | UnsafeDeserialization.rb:173:24:173:32 | call to readlines | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:173:24:173:32 | call to readlines | value from stdin |
|
||||
|
||||
@@ -1 +1 @@
|
||||
queries/security/cwe-502/UnsafeDeserialization.ql
|
||||
queries/security/cwe-502/UnsafeDeserialization.ql
|
||||
|
||||
@@ -142,18 +142,6 @@ class UsersController < ActionController::Base
|
||||
object = parse_output.to_ruby
|
||||
object = Psych.parse(yaml_data).to_ruby
|
||||
object = Psych.parse_file(yaml_data).to_ruby
|
||||
parsed_yaml = Psych.parse_stream(yaml_data)
|
||||
parsed_yaml.children.each do |child|
|
||||
object = child.to_ruby
|
||||
end
|
||||
Psych.parse_stream(yaml_data) do |document|
|
||||
object = document.to_ruby
|
||||
end
|
||||
object = parsed_yaml.children.first.to_ruby
|
||||
content = parsed_yaml.children[0].children[0].children
|
||||
object = parsed_yaml.to_ruby[0]
|
||||
object = content.to_ruby[0]
|
||||
object = Psych.parse(yaml_data).children[0].to_ruby
|
||||
end
|
||||
|
||||
# BAD
|
||||
@@ -184,4 +172,4 @@ class UsersController < ActionController::Base
|
||||
# Kernel.readlines
|
||||
object = YAML.load readlines
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user