I'm trying to wrap my head around remote code execution vulnerabilities in ruby/rails when contantize
is used.
I understand that being able to provide any class name to the server could be potentially dangerous, but I'm wondering if this by itself is dangerous.
for example, if a rails controller code looks something like this (i.e. executes a hardcoded method on the instantiated object):
klass = params[:class].classify.constantize
klass.do_something_with_id(params[:id]) if klass.respond_to?('do_something_with_id')
Is this code vulnerable? Or only in combination with being able to also specify the method to be called on the class?
Turning a string into a constant isn't dangerous in itself, but how that constant is used is potentially dangerous (i.e. the method that is then called).
If you really need to do this, then it's probably best to provide a list of classes that are allowed. E.g.
klass = params[:class].classify
if %w(Class1 Class2 Class3).include? klass
klass.constantize.do_something_with_id(params[:id])
else
raise 'Forbidden'
end
However it's done, it helps you to sleep at night to know that the input is considerably limited.
Another way of controlling the creation, which is more explicit but also more verbose, is to use a case statement:
def create_klass(option)
case option
when "option1"
Class1
when "option2"
Class2
when "option3"
Class3
else
raise "Unknown option"
end
end
This way, you don't need to expose the internals of your system to the client. If there are many options, then you could use a hash with options mapping to classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With