-
-
Save dissolved/09e9cc5e774985b33366 to your computer and use it in GitHub Desktop.
def string_to_camelcase(string) | |
string.gsub(/\s+/, "").camelize # camelize defined in Rails API | |
end | |
the_class = eval string_to_camelcase(params[:user_input]) | |
the_object = the_class.new(params[:more_user_input],params[:even_more_user_input]) |
Ruby is very whitespace forgiving too: ;puts'foobar'
is valid Ruby.
So combine all that with base64 encoding/decoding, URL encoding/decoding, YAML, etc. you're in for a world of pain.
Yes, the code wanted to call new on a class name. I agree it isn't the way to do it, I didn't write it! I don't have time to refactor this bit now either, but I did put a sanitizer in: render_404 and return unless TheClass.names.include?(params[:user_input])
. So at least arbitrary code can't be executed.
I suggest adding constantize
to that code. This should protect you a bit better, though I'm not 100% sure you still aren't vulnerable to something.
Something like:
def string_to_class(string)
# .constantize will raise a NameError if the class is not defined
string.gsub(/\s+/, "").camelize.constantize
end
the_class = string_to_class(params[:user_input])
the_object = the_class.new(params[:more_user_input],params[:even_more_user_input])
Also, I may try to impose a whitelist approach of what I want to allow:
string.gsub(/[^\w:]+/, '').camelize.constantize)
Agreed, no need for eval at all here... constantize
gets the job done with less risk. Great comments. Thanks again!
My question would be what's the intent? Are you looking for say a constant or class name? If so
eval
is not what you want.