Merge pull request #14544 from p-/p--oj-ox-unsafe-deser

Ruby: additional unsafe deserialization sinks for ox and one for oj
This commit is contained in:
Arthur Baars
2024-01-30 19:28:32 +01:00
committed by GitHub
10 changed files with 310 additions and 117 deletions

View File

@@ -126,13 +126,10 @@ module UnsafeDeserialization {
}
}
private string getAKnownOjModeName(boolean isSafe) {
result = ["compat", "custom", "json", "null", "rails", "strict", "wab"] and isSafe = true
or
result = "object" and isSafe = false
}
private predicate isOjModePair(CfgNodes::ExprNodes::PairCfgNode p, string modeValue) {
/**
* Oj/Ox common code to establish whether a deserialization mode is defined.
*/
private predicate isModePair(CfgNodes::ExprNodes::PairCfgNode p, string modeValue) {
p.getKey().getConstantValue().isStringlikeValue("mode") and
DataFlow::exprNode(p.getValue()).getALocalSource().getConstantValue().isSymbol(modeValue)
}
@@ -140,28 +137,31 @@ module UnsafeDeserialization {
/**
* A node representing a hash that contains the key `:mode`.
*/
private class OjOptionsHashWithModeKey extends DataFlow::Node {
private class OptionsHashWithModeKey extends DataFlow::Node {
private string modeValue;
OjOptionsHashWithModeKey() {
OptionsHashWithModeKey() {
exists(DataFlow::LocalSourceNode options |
options.flowsTo(this) and
isOjModePair(options.asExpr().(CfgNodes::ExprNodes::HashLiteralCfgNode).getAKeyValuePair(),
isModePair(options.asExpr().(CfgNodes::ExprNodes::HashLiteralCfgNode).getAKeyValuePair(),
modeValue)
)
}
/**
* Holds if this hash node contains a `:mode` key whose value is one known
* to be `isSafe` with untrusted data.
* Holds if this hash node contains the `:mode`
*/
predicate hasKnownMode(boolean isSafe) { modeValue = getAKnownOjModeName(isSafe) }
predicate hasKnownMode(string mode) { modeValue = mode }
}
/**
* Holds if this hash node contains a `:mode` key whose value is one of the
* `Oj` modes known to be safe to use with untrusted data.
*/
predicate hasSafeMode() { this.hasKnownMode(true) }
/**
* Unsafe deserialization utilizing the Oj gem
* See: https://github.com/ohler55/oj
*/
private string getAKnownOjModeName(boolean isSafe) {
result = ["compat", "custom", "json", "null", "rails", "strict", "wab"] and isSafe = true
or
result = "object" and isSafe = false
}
/**
@@ -179,10 +179,7 @@ module UnsafeDeserialization {
/**
* Gets the value being assigned to `Oj.default_options`.
*/
DataFlow::Node getValue() {
result.asExpr() =
this.getArgument(0).asExpr().(CfgNodes::ExprNodes::AssignExprCfgNode).getRhs()
}
DataFlow::Node getValue() { result = this.getArgument(0) }
}
/**
@@ -197,9 +194,9 @@ module UnsafeDeserialization {
*/
predicate hasExplicitKnownMode(boolean isSafe) {
exists(DataFlow::Node arg, int i | i >= 1 and arg = this.getArgument(i) |
arg.(OjOptionsHashWithModeKey).hasKnownMode(isSafe)
arg.(OptionsHashWithModeKey).hasKnownMode(getAKnownOjModeName(isSafe))
or
isOjModePair(arg.asExpr(), getAKnownOjModeName(isSafe))
isModePair(arg.asExpr(), getAKnownOjModeName(isSafe))
)
}
}
@@ -223,13 +220,106 @@ module UnsafeDeserialization {
// anywhere to set the default options to a known safe mode.
not ojLoad.hasExplicitKnownMode(_) and
not exists(SetOjDefaultOptionsCall setOpts |
setOpts.getValue().(OjOptionsHashWithModeKey).hasSafeMode()
setOpts.getValue().(OptionsHashWithModeKey).hasKnownMode(getAKnownOjModeName(true))
)
)
)
}
}
/**
* The first argument in a call to `Oj.object_load`, always considered as a
* sink for unsafe deserialization. (global and local mode options are ignored)
*/
private class OjObjectLoadArgument extends Sink {
OjObjectLoadArgument() {
this = API::getTopLevelMember("Oj").getAMethodCall("object_load").getArgument(0)
}
}
/**
* Unsafe deserialization utilizing the Ox gem
* See: https://github.com/ohler55/ox
*/
private string getAKnownOxModeName(boolean isSafe) {
result = ["generic", "limited", "hash", "hash_no_attrs"] and isSafe = true
or
result = "object" and isSafe = false
}
/**
* A call node that sets `Ox.default_options`.
*
* ```rb
* Ox.default_options = { mode: :limited, effort: :tolerant }
* ```
*/
private class SetOxDefaultOptionsCall extends DataFlow::CallNode {
SetOxDefaultOptionsCall() {
this = API::getTopLevelMember("Ox").getAMethodCall("default_options=")
}
/**
* Gets the value being assigned to `Ox.default_options`.
*/
DataFlow::Node getValue() { result = this.getArgument(0) }
}
/**
* A call to `Ox.load`.
*/
private class OxLoadCall extends DataFlow::CallNode {
OxLoadCall() { this = API::getTopLevelMember("Ox").getAMethodCall("load") }
/**
* Holds if this call to `Ox.load` includes an explicit options hash
* argument that sets the mode to one that is known to be `isSafe`.
*/
predicate hasExplicitKnownMode(boolean isSafe) {
exists(DataFlow::Node arg, int i | i >= 1 and arg = this.getArgument(i) |
arg.(OptionsHashWithModeKey).hasKnownMode(getAKnownOxModeName(isSafe))
or
isModePair(arg.asExpr(), getAKnownOxModeName(isSafe))
)
}
}
/**
* An argument in a call to `Ox.load` where the mode is `:object` (not the default),
* considered a sink for unsafe deserialization.
*/
class UnsafeOxLoadArgument extends Sink {
UnsafeOxLoadArgument() {
exists(OxLoadCall oxLoad |
this = oxLoad.getArgument(0) and
// Exclude calls that explicitly pass a safe mode option.
not oxLoad.hasExplicitKnownMode(true) and
(
// Sinks to include:
// - Calls with an explicit, unsafe mode option.
oxLoad.hasExplicitKnownMode(false)
or
// - Calls with no explicit mode option and there exists a call
// anywhere to set the default options to an unsafe mode (object).
not oxLoad.hasExplicitKnownMode(_) and
exists(SetOxDefaultOptionsCall setOpts |
setOpts.getValue().(OptionsHashWithModeKey).hasKnownMode(getAKnownOxModeName(false))
)
)
)
}
}
/**
* The first argument in a call to `Ox.parse_obj`, always considered as a
* sink for unsafe deserialization.
*/
class OxParseObjArgument extends Sink {
OxParseObjArgument() {
this = API::getTopLevelMember("Ox").getAMethodCall("parse_obj").getArgument(0)
}
}
/**
* An argument in a call to `Plist.parse_xml` where `marshal` is `true` (which is
* the default), considered a sink for unsafe deserialization.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added new unsafe deserialization sinks for the ox gem.
* Added an additional unsafe deserialization sink for the oj gem.

View File

@@ -27,6 +27,13 @@ method. In <code>psych</code> version 4.0.0 and above, the <code>load</code> met
safely be used.
</p>
<p>
If deserializing an untrusted XML document using the <code>ox</code> gem,
do not use <code>parse_obj</code> and <code>load</code> using the non-default :object mode.
Instead use the <code>load</code> method in the default mode or better explicitly set a safe
mode such as :hash.
</p>
<p>
To safely deserialize <a href="https://en.wikipedia.org/wiki/Property_list">Property List</a>
files using the <code>plist</code> gem, ensure that you pass <code>marshal: false</code>
@@ -37,8 +44,8 @@ when calling <code>Plist.parse_xml</code>.
<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
<code>JSON.load</code>, <code>YAML.load</code>, <code>Oj.load</code> and <code>Ox.parse_obj</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"/>

View File

@@ -23,4 +23,9 @@ class UserController < ActionController::Base
object = Oj.load params[:json]
# ...
end
def ox_example
object = Ox.parse_obj params[:xml]
# ...
end
end

View File

@@ -0,0 +1,16 @@
require "ox"
class UsersController < ActionController::Base
# BAD - Ox.load is unsafe when the mode :object is set globally
def route0
xml_data = params[:key]
object = Ox.load xml_data
end
# GOOD - the unsafe mode set globally is overridden with an insecure mode passed as
# a call argument
def route1
xml_data = params[:key]
object = Ox.load xml_data, mode: :generic
end
end

View File

@@ -0,0 +1,5 @@
require "ox"
# Set the default mode for the Ox library to use the :object mode, which makes
# Ox.load unsafe for untrusted data.
Ox.default_options = { :mode => :object }

View File

@@ -0,0 +1,12 @@
edges
| OxGlobalOptions.rb:6:5:6:12 | xml_data | OxGlobalOptions.rb:7:22:7:29 | xml_data |
| OxGlobalOptions.rb:6:16:6:21 | call to params | OxGlobalOptions.rb:6:16:6:27 | ...[...] |
| OxGlobalOptions.rb:6:16:6:27 | ...[...] | OxGlobalOptions.rb:6:5:6:12 | xml_data |
nodes
| OxGlobalOptions.rb:6:5:6:12 | xml_data | semmle.label | xml_data |
| OxGlobalOptions.rb:6:16:6:21 | call to params | semmle.label | call to params |
| OxGlobalOptions.rb:6:16:6:27 | ...[...] | semmle.label | ...[...] |
| OxGlobalOptions.rb:7:22:7:29 | xml_data | semmle.label | xml_data |
subpaths
#select
| OxGlobalOptions.rb:7:22:7:29 | xml_data | OxGlobalOptions.rb:6:16:6:21 | call to params | OxGlobalOptions.rb:7:22:7:29 | xml_data | Unsafe deserialization depends on a $@. | OxGlobalOptions.rb:6:16:6:21 | call to params | user-provided value |

View File

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

View File

@@ -1,36 +1,45 @@
edges
| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] |
| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] |
| UnsafeDeserialization.rb:10:5:10:19 | serialized_data | UnsafeDeserialization.rb:11:27:11:41 | serialized_data |
| UnsafeDeserialization.rb:10:23:10:50 | call to decode64 | UnsafeDeserialization.rb:10:5:10:19 | serialized_data |
| UnsafeDeserialization.rb:10:39:10:44 | call to params | UnsafeDeserialization.rb:10:39:10:50 | ...[...] |
| UnsafeDeserialization.rb:10:39:10:50 | ...[...] | UnsafeDeserialization.rb:10:23:10:50 | call to decode64 |
| UnsafeDeserialization.rb:16:5:16:19 | serialized_data | UnsafeDeserialization.rb:17:30:17:44 | serialized_data |
| UnsafeDeserialization.rb:16:23:16:50 | call to decode64 | UnsafeDeserialization.rb:16:5:16:19 | serialized_data |
| UnsafeDeserialization.rb:16:39:16:44 | call to params | UnsafeDeserialization.rb:16:39:16:50 | ...[...] |
| UnsafeDeserialization.rb:16:39:16:50 | ...[...] | UnsafeDeserialization.rb:16:23:16:50 | call to decode64 |
| UnsafeDeserialization.rb:22:5:22:13 | json_data | UnsafeDeserialization.rb:23:24:23:32 | json_data |
| UnsafeDeserialization.rb:22:17:22:22 | call to params | UnsafeDeserialization.rb:22:17:22:28 | ...[...] |
| UnsafeDeserialization.rb:22:17:22:28 | ...[...] | UnsafeDeserialization.rb:22:5:22:13 | json_data |
| UnsafeDeserialization.rb:28:5:28:13 | json_data | UnsafeDeserialization.rb:29:27:29:35 | json_data |
| UnsafeDeserialization.rb:28:17:28:22 | call to params | UnsafeDeserialization.rb:28:17:28:28 | ...[...] |
| UnsafeDeserialization.rb:28:17:28:28 | ...[...] | UnsafeDeserialization.rb:28:5:28:13 | json_data |
| UnsafeDeserialization.rb:40:5:40:13 | yaml_data | UnsafeDeserialization.rb:41:24:41:32 | yaml_data |
| UnsafeDeserialization.rb:40:17:40:22 | call to params | UnsafeDeserialization.rb:40:17:40:28 | ...[...] |
| UnsafeDeserialization.rb:40:17:40:28 | ...[...] | UnsafeDeserialization.rb:40:5:40:13 | yaml_data |
| UnsafeDeserialization.rb:52:5:52:13 | json_data | UnsafeDeserialization.rb:53:22:53:30 | json_data |
| UnsafeDeserialization.rb:52:5:52:13 | json_data | UnsafeDeserialization.rb:54:22:54:30 | json_data |
| UnsafeDeserialization.rb:52:17:52:22 | call to params | UnsafeDeserialization.rb:52:17:52:28 | ...[...] |
| UnsafeDeserialization.rb:52:17:52:28 | ...[...] | UnsafeDeserialization.rb:52:5:52:13 | json_data |
| UnsafeDeserialization.rb:59:5:59:13 | json_data | UnsafeDeserialization.rb:69:23:69:31 | json_data |
| UnsafeDeserialization.rb:59:17:59:22 | call to params | UnsafeDeserialization.rb:59:17:59:28 | ...[...] |
| UnsafeDeserialization.rb:59:17:59:28 | ...[...] | UnsafeDeserialization.rb:59:5:59:13 | json_data |
| UnsafeDeserialization.rb:81:5:81:7 | xml | UnsafeDeserialization.rb:82:34:82:36 | xml |
| UnsafeDeserialization.rb:81:11:81:16 | call to params | UnsafeDeserialization.rb:81:11:81:22 | ...[...] |
| UnsafeDeserialization.rb:81:11:81:22 | ...[...] | UnsafeDeserialization.rb:81:5:81:7 | xml |
| UnsafeDeserialization.rb:87:5:87:13 | yaml_data | UnsafeDeserialization.rb:88:25:88:33 | yaml_data |
| UnsafeDeserialization.rb:87:17:87:22 | call to params | UnsafeDeserialization.rb:87:17:87:28 | ...[...] |
| UnsafeDeserialization.rb:87:17:87:28 | ...[...] | UnsafeDeserialization.rb:87:5:87:13 | yaml_data |
| UnsafeDeserialization.rb:11:5:11:19 | serialized_data | UnsafeDeserialization.rb:12:27:12:41 | serialized_data |
| UnsafeDeserialization.rb:11:23:11:50 | call to decode64 | UnsafeDeserialization.rb:11:5:11:19 | serialized_data |
| UnsafeDeserialization.rb:11:39:11:44 | call to params | UnsafeDeserialization.rb:11:39:11:50 | ...[...] |
| UnsafeDeserialization.rb:11:39:11:50 | ...[...] | UnsafeDeserialization.rb:11:23:11:50 | call to decode64 |
| UnsafeDeserialization.rb:17:5:17:19 | serialized_data | UnsafeDeserialization.rb:18:30:18:44 | serialized_data |
| UnsafeDeserialization.rb:17:23:17:50 | call to decode64 | UnsafeDeserialization.rb:17:5:17:19 | serialized_data |
| UnsafeDeserialization.rb:17:39:17:44 | call to params | UnsafeDeserialization.rb:17:39:17:50 | ...[...] |
| UnsafeDeserialization.rb:17:39:17:50 | ...[...] | UnsafeDeserialization.rb:17:23:17:50 | call to decode64 |
| UnsafeDeserialization.rb:23:5:23:13 | json_data | UnsafeDeserialization.rb:24:24:24:32 | json_data |
| UnsafeDeserialization.rb:23:17:23:22 | call to params | UnsafeDeserialization.rb:23:17:23:28 | ...[...] |
| UnsafeDeserialization.rb:23:17:23:28 | ...[...] | UnsafeDeserialization.rb:23:5:23:13 | json_data |
| UnsafeDeserialization.rb:29:5:29:13 | json_data | UnsafeDeserialization.rb:30:27:30:35 | json_data |
| UnsafeDeserialization.rb:29:17:29:22 | call to params | UnsafeDeserialization.rb:29:17:29:28 | ...[...] |
| UnsafeDeserialization.rb:29:17:29:28 | ...[...] | UnsafeDeserialization.rb:29:5:29:13 | json_data |
| UnsafeDeserialization.rb:41:5:41:13 | yaml_data | UnsafeDeserialization.rb:42:24:42:32 | yaml_data |
| UnsafeDeserialization.rb:41:17:41:22 | call to params | UnsafeDeserialization.rb:41:17:41:28 | ...[...] |
| UnsafeDeserialization.rb:41:17:41:28 | ...[...] | UnsafeDeserialization.rb:41:5:41:13 | yaml_data |
| UnsafeDeserialization.rb:53:5:53:13 | json_data | UnsafeDeserialization.rb:54:22:54:30 | json_data |
| UnsafeDeserialization.rb:53:5:53:13 | json_data | UnsafeDeserialization.rb:55:22:55:30 | json_data |
| UnsafeDeserialization.rb:53:17:53:22 | call to params | UnsafeDeserialization.rb:53:17:53:28 | ...[...] |
| UnsafeDeserialization.rb:53:17:53:28 | ...[...] | UnsafeDeserialization.rb:53:5:53:13 | json_data |
| UnsafeDeserialization.rb:60:5:60:13 | json_data | UnsafeDeserialization.rb:70:23:70:31 | json_data |
| UnsafeDeserialization.rb:60:17:60:22 | call to params | UnsafeDeserialization.rb:60:17:60:28 | ...[...] |
| UnsafeDeserialization.rb:60:17:60:28 | ...[...] | UnsafeDeserialization.rb:60:5:60:13 | json_data |
| UnsafeDeserialization.rb:81:4:81:12 | json_data | UnsafeDeserialization.rb:82:28:82:36 | json_data |
| UnsafeDeserialization.rb:81:16:81:21 | call to params | UnsafeDeserialization.rb:81:16:81:27 | ...[...] |
| UnsafeDeserialization.rb:81:16:81:27 | ...[...] | UnsafeDeserialization.rb:81:4:81:12 | json_data |
| UnsafeDeserialization.rb:87:4:87:11 | xml_data | UnsafeDeserialization.rb:88:26:88:33 | xml_data |
| UnsafeDeserialization.rb:87:15:87:20 | call to params | UnsafeDeserialization.rb:87:15:87:26 | ...[...] |
| UnsafeDeserialization.rb:87:15:87:26 | ...[...] | UnsafeDeserialization.rb:87:4:87:11 | xml_data |
| UnsafeDeserialization.rb:93:5:93:12 | xml_data | UnsafeDeserialization.rb:94:22:94:29 | xml_data |
| UnsafeDeserialization.rb:93:16:93:21 | call to params | UnsafeDeserialization.rb:93:16:93:27 | ...[...] |
| UnsafeDeserialization.rb:93:16:93:27 | ...[...] | UnsafeDeserialization.rb:93:5:93:12 | xml_data |
| UnsafeDeserialization.rb:109:5:109:7 | xml | UnsafeDeserialization.rb:110:34:110:36 | xml |
| UnsafeDeserialization.rb:109:11:109:16 | call to params | UnsafeDeserialization.rb:109:11:109:22 | ...[...] |
| UnsafeDeserialization.rb:109:11:109:22 | ...[...] | UnsafeDeserialization.rb:109:5:109:7 | xml |
| UnsafeDeserialization.rb:115:5:115:13 | yaml_data | UnsafeDeserialization.rb:116:25:116:33 | yaml_data |
| UnsafeDeserialization.rb:115:17:115:22 | call to params | UnsafeDeserialization.rb:115:17:115:28 | ...[...] |
| UnsafeDeserialization.rb:115:17:115:28 | ...[...] | UnsafeDeserialization.rb:115:5:115:13 | yaml_data |
| YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] |
| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] |
| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] |
@@ -46,50 +55,62 @@ nodes
| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | semmle.label | ...[...] |
| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | semmle.label | call to params |
| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:10:5:10:19 | serialized_data | semmle.label | serialized_data |
| UnsafeDeserialization.rb:10:23:10:50 | call to decode64 | semmle.label | call to decode64 |
| UnsafeDeserialization.rb:10:39:10:44 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:10:39:10:50 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:11:27:11:41 | serialized_data | semmle.label | serialized_data |
| UnsafeDeserialization.rb:16:5:16:19 | serialized_data | semmle.label | serialized_data |
| UnsafeDeserialization.rb:16:23:16:50 | call to decode64 | semmle.label | call to decode64 |
| UnsafeDeserialization.rb:16:39:16:44 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:16:39:16:50 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:17:30:17:44 | serialized_data | semmle.label | serialized_data |
| UnsafeDeserialization.rb:22:5:22:13 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:22:17:22:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:22:17:22:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:23:24:23:32 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:28:5:28:13 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:28:17:28:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:28:17:28:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:29:27:29:35 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:40:5:40:13 | yaml_data | semmle.label | yaml_data |
| UnsafeDeserialization.rb:40:17:40:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:40:17:40:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:41:24:41:32 | yaml_data | semmle.label | yaml_data |
| UnsafeDeserialization.rb:52:5:52:13 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:52:17:52:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:52:17:52:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:53:22:53:30 | json_data | semmle.label | json_data |
| 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 |
| UnsafeDeserialization.rb:11:39:11:44 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:11:39:11:50 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:12:27:12:41 | serialized_data | semmle.label | serialized_data |
| UnsafeDeserialization.rb:17:5:17:19 | serialized_data | semmle.label | serialized_data |
| UnsafeDeserialization.rb:17:23:17:50 | call to decode64 | semmle.label | call to decode64 |
| UnsafeDeserialization.rb:17:39:17:44 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:17:39:17:50 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:18:30:18:44 | serialized_data | semmle.label | serialized_data |
| UnsafeDeserialization.rb:23:5:23:13 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:23:17:23:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:23:17:23:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:24:24:24:32 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:29:5:29:13 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:29:17:29:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:29:17:29:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:30:27:30:35 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:41:5:41:13 | yaml_data | semmle.label | yaml_data |
| UnsafeDeserialization.rb:41:17:41:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:41:17:41:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:42:24:42:32 | yaml_data | semmle.label | yaml_data |
| UnsafeDeserialization.rb:53:5:53:13 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:53:17:53:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:53:17:53:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:54:22:54:30 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:59:5:59:13 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:59:17:59:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:59:17:59:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:69:23:69:31 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:81:5:81:7 | xml | semmle.label | xml |
| UnsafeDeserialization.rb:81:11:81:16 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:81:11:81:22 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:82:34:82:36 | xml | semmle.label | xml |
| UnsafeDeserialization.rb:87:5:87:13 | yaml_data | semmle.label | yaml_data |
| UnsafeDeserialization.rb:87:17:87:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:87:17:87:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:88:25:88:33 | yaml_data | semmle.label | yaml_data |
| UnsafeDeserialization.rb:92:24:92:34 | call to read | semmle.label | call to read |
| UnsafeDeserialization.rb:95:24:95:33 | call to gets | semmle.label | call to gets |
| UnsafeDeserialization.rb:98:24:98:32 | call to read | semmle.label | call to read |
| UnsafeDeserialization.rb:101:24:101:27 | call to gets | semmle.label | call to gets |
| UnsafeDeserialization.rb:104:24:104:32 | call to readlines | semmle.label | call to readlines |
| UnsafeDeserialization.rb:55:22:55:30 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:60:5:60:13 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:60:17:60:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:60:17:60:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:70:23:70:31 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:81:4:81:12 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:81:16:81:21 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:81:16:81:27 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:82:28:82:36 | json_data | semmle.label | json_data |
| UnsafeDeserialization.rb:87:4:87:11 | xml_data | semmle.label | xml_data |
| UnsafeDeserialization.rb:87:15:87:20 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:87:15:87:26 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:88:26:88:33 | xml_data | semmle.label | xml_data |
| UnsafeDeserialization.rb:93:5:93:12 | xml_data | semmle.label | xml_data |
| UnsafeDeserialization.rb:93:16:93:21 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:93:16:93:27 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:94:22:94:29 | xml_data | semmle.label | xml_data |
| UnsafeDeserialization.rb:109:5:109:7 | xml | semmle.label | xml |
| UnsafeDeserialization.rb:109:11:109:16 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:109:11:109:22 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:110:34:110:36 | xml | semmle.label | xml |
| UnsafeDeserialization.rb:115:5:115:13 | yaml_data | semmle.label | yaml_data |
| UnsafeDeserialization.rb:115:17:115:22 | call to params | semmle.label | call to params |
| UnsafeDeserialization.rb:115:17:115:28 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:116:25:116:33 | yaml_data | semmle.label | yaml_data |
| UnsafeDeserialization.rb:120:24:120:34 | call to read | semmle.label | call to read |
| UnsafeDeserialization.rb:123:24:123:33 | call to gets | semmle.label | call to gets |
| UnsafeDeserialization.rb:126:24:126:32 | call to read | semmle.label | call to read |
| UnsafeDeserialization.rb:129:24:129:27 | call to gets | semmle.label | call to gets |
| UnsafeDeserialization.rb:132:24:132:32 | call to readlines | semmle.label | call to readlines |
| YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | semmle.label | call to params |
| YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] | semmle.label | ...[...] |
| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | semmle.label | call to params |
@@ -111,21 +132,24 @@ subpaths
#select
| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | user-provided value |
| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | user-provided value |
| UnsafeDeserialization.rb:11:27:11:41 | serialized_data | UnsafeDeserialization.rb:10:39:10:44 | call to params | UnsafeDeserialization.rb:11:27:11:41 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:10:39:10:44 | call to params | user-provided value |
| UnsafeDeserialization.rb:17:30:17:44 | serialized_data | UnsafeDeserialization.rb:16:39:16:44 | call to params | UnsafeDeserialization.rb:17:30:17:44 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:16:39:16:44 | call to params | user-provided value |
| UnsafeDeserialization.rb:23:24:23:32 | json_data | UnsafeDeserialization.rb:22:17:22:22 | call to params | UnsafeDeserialization.rb:23:24:23:32 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:22:17:22:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:29:27:29:35 | json_data | UnsafeDeserialization.rb:28:17:28:22 | call to params | UnsafeDeserialization.rb:29:27:29:35 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:28:17:28:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:41:24:41:32 | yaml_data | UnsafeDeserialization.rb:40:17:40:22 | call to params | UnsafeDeserialization.rb:41:24:41:32 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:40:17:40:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:53:22:53:30 | json_data | UnsafeDeserialization.rb:52:17:52:22 | call to params | UnsafeDeserialization.rb:53:22:53:30 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:52:17:52:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:54:22:54:30 | json_data | UnsafeDeserialization.rb:52:17:52:22 | call to params | UnsafeDeserialization.rb:54:22:54:30 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:52:17:52:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:69:23:69:31 | json_data | UnsafeDeserialization.rb:59:17:59:22 | call to params | UnsafeDeserialization.rb:69:23:69:31 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:59:17:59:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:82:34:82:36 | xml | UnsafeDeserialization.rb:81:11:81:16 | call to params | UnsafeDeserialization.rb:82:34:82:36 | xml | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:81:11:81:16 | call to params | user-provided value |
| UnsafeDeserialization.rb:88:25:88:33 | yaml_data | UnsafeDeserialization.rb:87:17:87:22 | call to params | UnsafeDeserialization.rb:88:25:88:33 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:87:17:87:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:92:24:92:34 | call to read | UnsafeDeserialization.rb:92:24:92:34 | call to read | UnsafeDeserialization.rb:92:24:92:34 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:92:24:92:34 | call to read | value from stdin |
| UnsafeDeserialization.rb:95:24:95:33 | call to gets | UnsafeDeserialization.rb:95:24:95:33 | call to gets | UnsafeDeserialization.rb:95:24:95:33 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:95:24:95:33 | call to gets | value from stdin |
| UnsafeDeserialization.rb:98:24:98:32 | call to read | UnsafeDeserialization.rb:98:24:98:32 | call to read | UnsafeDeserialization.rb:98:24:98:32 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:98:24:98:32 | call to read | value from stdin |
| UnsafeDeserialization.rb:101:24:101:27 | call to gets | UnsafeDeserialization.rb:101:24:101:27 | call to gets | UnsafeDeserialization.rb:101:24:101:27 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:101:24:101:27 | call to gets | value from stdin |
| UnsafeDeserialization.rb:104:24:104:32 | call to readlines | UnsafeDeserialization.rb:104:24:104:32 | call to readlines | UnsafeDeserialization.rb:104:24:104:32 | call to readlines | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:104:24:104:32 | call to readlines | value from stdin |
| 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 |
| UnsafeDeserialization.rb:18:30:18:44 | serialized_data | UnsafeDeserialization.rb:17:39:17:44 | call to params | UnsafeDeserialization.rb:18:30:18:44 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:17:39:17:44 | call to params | user-provided value |
| UnsafeDeserialization.rb:24:24:24:32 | json_data | UnsafeDeserialization.rb:23:17:23:22 | call to params | UnsafeDeserialization.rb:24:24:24:32 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:23:17:23:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:30:27:30:35 | json_data | UnsafeDeserialization.rb:29:17:29:22 | call to params | UnsafeDeserialization.rb:30:27:30:35 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:29:17:29:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:42:24:42:32 | yaml_data | UnsafeDeserialization.rb:41:17:41:22 | call to params | UnsafeDeserialization.rb:42:24:42:32 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:41:17:41:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:54:22:54:30 | json_data | UnsafeDeserialization.rb:53:17:53:22 | call to params | UnsafeDeserialization.rb:54:22:54:30 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:53:17:53:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:55:22:55:30 | json_data | UnsafeDeserialization.rb:53:17:53:22 | call to params | UnsafeDeserialization.rb:55:22:55:30 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:53:17:53:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:70:23:70:31 | json_data | UnsafeDeserialization.rb:60:17:60:22 | call to params | UnsafeDeserialization.rb:70:23:70:31 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:60:17:60:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:82:28:82:36 | json_data | UnsafeDeserialization.rb:81:16:81:21 | call to params | UnsafeDeserialization.rb:82:28:82:36 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:81:16:81:21 | call to params | user-provided value |
| UnsafeDeserialization.rb:88:26:88:33 | xml_data | UnsafeDeserialization.rb:87:15:87:20 | call to params | UnsafeDeserialization.rb:88:26:88:33 | xml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:87:15:87:20 | call to params | user-provided value |
| UnsafeDeserialization.rb:94:22:94:29 | xml_data | UnsafeDeserialization.rb:93:16:93:21 | call to params | UnsafeDeserialization.rb:94:22:94:29 | xml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:93:16:93:21 | call to params | user-provided value |
| UnsafeDeserialization.rb:110:34:110:36 | xml | UnsafeDeserialization.rb:109:11:109:16 | call to params | UnsafeDeserialization.rb:110:34:110:36 | xml | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:109:11:109:16 | call to params | user-provided value |
| UnsafeDeserialization.rb:116:25:116:33 | yaml_data | UnsafeDeserialization.rb:115:17:115:22 | call to params | UnsafeDeserialization.rb:116:25:116:33 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:115:17:115:22 | call to params | user-provided value |
| UnsafeDeserialization.rb:120:24:120:34 | call to read | UnsafeDeserialization.rb:120:24:120:34 | call to read | UnsafeDeserialization.rb:120:24:120:34 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:120:24:120:34 | call to read | value from stdin |
| UnsafeDeserialization.rb:123:24:123:33 | call to gets | UnsafeDeserialization.rb:123:24:123:33 | call to gets | UnsafeDeserialization.rb:123:24:123:33 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:123:24:123:33 | call to gets | value from stdin |
| UnsafeDeserialization.rb:126:24:126:32 | call to read | UnsafeDeserialization.rb:126:24:126:32 | call to read | UnsafeDeserialization.rb:126:24:126:32 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:126:24:126:32 | call to read | value from stdin |
| UnsafeDeserialization.rb:129:24:129:27 | call to gets | UnsafeDeserialization.rb:129:24:129:27 | call to gets | UnsafeDeserialization.rb:129:24:129:27 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:129:24:129:27 | call to gets | value from stdin |
| UnsafeDeserialization.rb:132:24:132:32 | call to readlines | UnsafeDeserialization.rb:132:24:132:32 | call to readlines | UnsafeDeserialization.rb:132:24:132:32 | call to readlines | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:132:24:132:32 | call to readlines | value from stdin |
| YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] | YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | user-provided value |
| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | user-provided value |
| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | user-provided value |

View File

@@ -2,6 +2,7 @@ require "active_job"
require "base64"
require "json"
require "oj"
require "ox"
require "yaml"
class UsersController < ActionController::Base
@@ -75,15 +76,42 @@ class UsersController < ActionController::Base
object = Oj.safe_load json_data
end
# BAD - Oj.object_load is always unsafe
def route10
json_data = params[:key]
object = Oj.object_load json_data
end
# BAD - Ox.parse_obj is always unsafe
def route11
xml_data = params[:key]
object = Ox.parse_obj xml_data
end
# BAD - Ox.load with :object mode is always unsafe
def route12
xml_data = params[:key]
object = Ox.load xml_data, mode: :object
end
# GOOD - Ox.load is safe in the default mode (which is :generic) and in any other mode than :object
def route13
xml_data = params[:key]
object1 = Ox.load xml_data
object2 = Ox.load xml_data, mode: :limited
object3 = Ox.load xml_data, mode: :hash
object4 = Ox.load xml_data, mode: :generic
end
# BAD - `Hash.from_trusted_xml` will deserialize elements with the
# `type="yaml"` attribute as YAML.
def route10
def route14
xml = params[:key]
hash = Hash.from_trusted_xml(xml)
end
# BAD
def route11
def route15
yaml_data = params[:key]
object = Psych.load yaml_data
end