2

I have a string:

parsed[tag] => "first_name: 'Richard'"

I need to execute code that looks like this:

client.put_if_absent("profiles", bot_client_name, {first_name: 'Richard'})

Is it possible I can use that first string to somehow act as code for the equivalent text? I tried using eval(parsed[tag]) but that was a fail.

I changed to the following:

response = "client.put_if_absent('profiles', bot_client_name, {#{parsed[tag]}})"

eval(response)

This actually works --- what can I do to reduce potential risks?

3
  • 3
    Don't do this. Better to use some minor parsing and use send if it's a white listed method name. I'd probably try to figure out ways around this requirement altogether. Commented Nov 27, 2014 at 0:13
  • 3
    Where does that string come from and why can't it be in a sensible string format such as JSON? Commented Nov 27, 2014 at 0:15
  • I could change the string. In this case "richard" is the user input and could be anything. What would I be able to do if it were in JSON? Commented Nov 27, 2014 at 11:02

3 Answers 3

3

Please do not use eval to parse user input. That is super dangerous, and you will never get it to be safe. Your real goal here appears to be take this string "first_name: 'Richard'" and make this object {first_name: 'Richard'} from it. You don't need eval to accomplish that task.

If you're trying to take user input, and turn it into an object hash, checkout this question. How do I convert a String object into a Hash object? I recommend looking at jackquack's answer in that post to give you an idea about how you can use the methods in Ruby's powerful String library (http://www.ruby-doc.org/core-2.1.4/String.html) to parse your input.

If your user input is in a standard format like JSON, YAML, XML, etc. then you can use a library that will do all this hard work for you. If your user input is in a custom format, such as seems to be your case, then you need to roll that parsing on your own.

Sign up to request clarification or add additional context in comments.

3 Comments

Using a standard format is ideal, but in a pinch semicolon-separated content is fine. split(/\s*:\s*/) does the job.
I used JSON.parse -- I just changed the format of the input, which I could adjust {"first_name": "<star/>"} via Crack
@Angela That's definitely the right approach if you can get there :)
0

It depends of course of what your tag will be, but what about just parsing it like this:

parsed_tag_hash = Hash[*parsed[tag].scan(/\w+/)]
# {"first_name"=>"Richard"}
client.put_if_absent("profiles", bot_client_name, parsed_tag_hash)

2 Comments

Hi what does the scan w+ do this seems like a direction I would like to go after testing it
@Angela the + tells the regex to take, if there is one, as much \w character as he can.
-1

Meta-answer, as I don't know Ruby:

Assuming that your string is user input, you need to make sure that it won't lead to anything being executed.

While this might be a tough problem in general, I think you can use known constraints about valid input for your issue to ensure it is not executable. Use regex to ensure there are no end-of-string chars or escape chars in the input that would allow eval to see it as anything other than as single string constant. HTH.

3 Comments

This is bad advice. A user should never use eval for simple string parsing, which is super dangerous. There are much better ways to skin this cat.
I am answering the queztion posed, not a different one about whether to do this or what alternatives would be safer. l happen to agree it is not a good or safe pattern in general. But if you want to disallow use of eval then a more strongly typed and less scripted language might be appropriate- the function is there in the language definition.
This site is full of novices. It isn't responsible advice giving to lead them down a dangerous path simply because they ask how to travel that road.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.