revert YAML.qll and yaml sinks to previous PR, make a separate experimental query only for yaml

This commit is contained in:
amammad
2023-10-04 18:21:12 +02:00
committed by Harry Maclean
parent c582ea626d
commit 32f5667bb6
15 changed files with 564 additions and 154 deletions

View File

@@ -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"]) }

View File

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

View File

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

View File

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

View File

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

View File

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

View 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"]) }

View File

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

View File

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

View File

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

View File

@@ -0,0 +1 @@
experimental/cwe-502/UnsafeYamlDeserialization.ql

View File

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

View File

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

View File

@@ -1 +1 @@
queries/security/cwe-502/UnsafeDeserialization.ql
queries/security/cwe-502/UnsafeDeserialization.ql

View File

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