-
-
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]) |
@dissolved I believe it's because it's not an underscore
And now that you've opened my eyes. I'm thinking of much worse that just erasing the app server!
Well yeah, you've let remote code execute on the server. They can do anything and everything.
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.
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!
Great! I knew it was dangerous. I guess I'm confused at why String#camelize leaves the
.eval
and.decode64
as lowercase... but it obviously does! Thanks again!