-
-
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]) |
# decodes to `ls`, but imagine `rm -rf /`
input = "Kernel.eval(Base64.decode64('YGxzYA==\n'))"
string_to_camelcase(input)
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!
@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!
This seems like very dangerous code. Yet calling string_to_camelcase prior to eval'ing the string is making it hard for me to dream up something destructive. I'm sure I'm missing all kinds of devious things, help me think of one to win my case.