tags:

views:

670

answers:

6

I'm working on a php project, and I want to run code that's fetched from a MySQL database. There's no chance of unsafe code being injected, so the only thing I'm worried about is performace. Should I use eval() so I can directly run the code, or parse it so that call_user_func() runs it instead?

For example, if the code I fetched was "myfunc(1,2,3); anotherFunc(3,2,1);"
I can eval() it directly to run the code.

But for call_user_func(), I'd have to parse the string so that it can be ran. So which is the better function to use in this case?

A: 

I would think that parsing would add overhead, but the only way you can be sure is to run tests it. Try it both ways with various functions and see what your results are. Use code that represents what you expect to store.

Good luck!

Todd R
+1  A: 

Use eval(). Anything else is not worth the effort - they wouldn't have any positive side effects.

soulmerge
+1  A: 

You might want to take a look at the runkit extention, which can execute php in a sandbox not effecting the running code.

If the code is suppose to effect your running code, go for eval().

Bob Fanger
+1  A: 

As a general rule, i always try to stay as far away from eval() as possible. This case, however, looks like a good candidate for it.

You say "There's no chance of unsafe code being injected", so the big question is: is there a chance of unworking code being in the database?

If not, eval() is the solution, but if there is then proper parsing and error logging/etc might be a safer bet. (i believe using call_user_func_array() is faster in theory, so any parsing overhead might become negligible)

jcinacio
+3  A: 

Storing PHP in the database is a bad design smell in itself; even though in this case you are pretty sure it can never contain unsafe code, it is always good to minimize the number of assumptions or defenses like that you have to make. If you store PHP code in the database, then an attack in which an attacker gains access to your database quickly becomes a lot more serious, turning into an attack in which an attacker can run arbitrary code! I know that having your database compromised like this is highly unlikely, but nonetheless it is good security practice not to let even an unlikely situation compromise your system more than it needs to.

Many people agree that eval() should always, without exception, be avoided in PHP code. There's always an alternative.

In this case, however, I think that I would have to say that using eval() would be the best solution for you, because you are already storing PHP code in the DB, so using eval() is not going to increase your risk any further than that.

I would, however, recommend that

  1. You try to validate the code before you eval() it, by being conservative in what you allow. Assume that somehow an attacker got into your database even thought that is unlikely.
  2. You at least give some serious thought to rewriting your application so that PHP code is not stored in a database. If you are storing complex data structures, think about something like JSON or even XML instead. Safe parsers exist for these.

I'm sorry if this answer seems a bit reactionary; I just happen to feel this sort of thing is very important.

thomasrutter
A: 

You should wrap the code you're about to run in a try/catch block too, in case there is an error (even though you said there won't be, there is a possibility, and it is best practice)

alex