Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

remote code execution in ruby with constantize

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?

like image 494
gingerlime Avatar asked Aug 27 '13 12:08

gingerlime


1 Answers

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.

Update

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.

like image 51
Jon Cairns Avatar answered Sep 22 '22 03:09

Jon Cairns