Ruby: add rb/unsafe-deserialization sinks for const_get args

This commit is contained in:
Alex Ford
2022-10-11 15:45:10 +01:00
parent a3f096a6bc
commit 3d08a2954d
3 changed files with 45 additions and 0 deletions

View File

@@ -8,6 +8,8 @@ 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
module UnsafeDeserialization {
/**
@@ -199,4 +201,27 @@ module UnsafeDeserialization {
toNode = callNode
)
}
/**
* A argument in a call to `Module.const_get`, considered as a sink for unsafe
* deserialization.
*
* Calls to `Module.const_get` can return arbitrary classes which can then be
* instantiated.
*/
class ConstGetCallArgument extends Sink {
ConstGetCallArgument() { this = any(Module::ModuleConstGetCallCodeExecution c).getCode() }
}
/**
* A argument in a call to `ActiveJob::Serializers.deserialize`, considered as
* a sink for unsafe deserialization.
*
* This is roughly equivalent to a call to `Module.const_get`.
*/
class ActiveJobSerializersDeserializeArgument extends Sink {
ActiveJobSerializersDeserializeArgument() {
this = any(ActiveJob::Serializers::DeserializeCall c).getCode()
}
}
}

View File

@@ -18,6 +18,8 @@ edges
| UnsafeDeserialization.rb:81:11:81:22 | ...[...] : | UnsafeDeserialization.rb:82:34:82:36 | xml |
| UnsafeDeserialization.rb:87:17:87:22 | call to params : | UnsafeDeserialization.rb:87:17:87:28 | ...[...] : |
| UnsafeDeserialization.rb:87:17:87:28 | ...[...] : | UnsafeDeserialization.rb:88:25:88:33 | yaml_data |
| UnsafeDeserialization.rb:93:30:93:35 | call to params : | UnsafeDeserialization.rb:93:30:93:43 | ...[...] |
| UnsafeDeserialization.rb:99:48:99:53 | call to params : | UnsafeDeserialization.rb:99:48:99:61 | ...[...] |
nodes
| UnsafeDeserialization.rb:10:39:10:44 | call to params : | semmle.label | call to params : |
| UnsafeDeserialization.rb:10:39:10:50 | ...[...] : | semmle.label | ...[...] : |
@@ -47,6 +49,10 @@ nodes
| 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:93:30:93:35 | call to params : | semmle.label | call to params : |
| UnsafeDeserialization.rb:93:30:93:43 | ...[...] | semmle.label | ...[...] |
| UnsafeDeserialization.rb:99:48:99:53 | call to params : | semmle.label | call to params : |
| UnsafeDeserialization.rb:99:48:99:61 | ...[...] | semmle.label | ...[...] |
subpaths
#select
| 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 |
@@ -59,3 +65,5 @@ subpaths
| 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:93:30:93:43 | ...[...] | UnsafeDeserialization.rb:93:30:93:35 | call to params : | UnsafeDeserialization.rb:93:30:93:43 | ...[...] | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:93:30:93:35 | call to params | user-provided value |
| UnsafeDeserialization.rb:99:48:99:61 | ...[...] | UnsafeDeserialization.rb:99:48:99:53 | call to params : | UnsafeDeserialization.rb:99:48:99:61 | ...[...] | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:99:48:99:53 | call to params | user-provided value |

View File

@@ -87,4 +87,16 @@ class UsersController < ActionController::Base
yaml_data = params[:key]
object = Psych.load yaml_data
end
# BAD - user input determines which class is instantiated
def route12
klass = Module.const_get(params[:class])
object = klass.new
end
# BAD - user input determines which class is instantiated
def route13
klass = ActiveJob::Serializers.deserialize(params[:class])
object = klass.new
end
end