6

The Official Documentation regarding eval() as function, says:

Among other things, this can be useful for storing code in a database text field for later execution.

I'm seriously confused about that. Is PHP Documentation suggesting to store PHP lines into databases? What? Isn't that something freaking unsafe?

What if i know that in the database there's a string that is executed as PHP? Isn't that extremely dangerous? I just need of an Sql injection to do whatever i want to that site, whatever i want. I can delete the entire database, i can get everything from the script, i can do everything.

How can this be so helpful?

Could you please provide me some examples on how this eval() can be usefull? Also, i am probably missing something, why have i seen some codes like:

eval("if (is_int($int)) { return false }");

instead of just

if (is_int($int)) { return false }

But, as i said, i am probably missing something: what?

Jonah
  • 9,991
  • 5
  • 45
  • 79
Shoe
  • 74,840
  • 36
  • 166
  • 272
  • 1
    Good question. I don't know of a use for `eval()` that can't be done better with something else. But I'm listening... – Jonah Jan 25 '11 at 18:30
  • seems like this point has been driven into the ground, `eval()` is bad, we get it. – jondavidjohn Jan 25 '11 at 18:33
  • 1
    Well having written a small script parser I can attest you that there are valid uses for eval. But apart from fringe cases, eval() is simply another name for include() and just doesn't depend on files. – mario Jan 25 '11 at 18:33
  • 2
    **eval** is there to complement **variable variables** and **direct sql string manipulation**. Wouldn't want to create anything unfair or unbalanced now! ;-) –  Jan 25 '11 at 18:36
  • Overall, it's okay that it's there. Just don't use it. :| – Jonah Jan 25 '11 at 18:40
  • Related: [When if ever is eval not evil?](http://stackoverflow.com/questions/3499672/when-if-ever-is-eval-not-evil) – NikiC Jan 25 '11 at 19:04

6 Answers6

7

The eval() function is fantastic! People use it all the time to inject code and gain excellent access to servers all the time. You'll often see the use of eval() and that regex function that also executes, among others, in broken WordPress installations.

There are very few reasons why you would need eval. For example, if I were making a PHP testing site where folks could enter some code on a page and then run it. Of course, it would need to be sanitized first, for the very reasons you listed.

Brad
  • 159,648
  • 54
  • 349
  • 530
  • When used correctly eval() is very useful. You can see some examples in many drupal modules (cck comes to mind) – AntonioCS Jan 25 '11 at 20:22
  • @AntonioCS, no doubt, but I can't tell you how many hacked Drupal (among others) installations I've had to fix because of it. I don't dispute that it can be useful, but I do think it leads to trouble. Nobody's code is perfect. Not even Jon Skeet's. (Or is it. :-D) – Brad Jan 25 '11 at 21:18
4

Let's say you had a CMS that allowed you to type PHP code. I can see using the eval function to evaluate that PHP snippet. Javascript also has eval for the same reason.

All reasons aside, eval is very unsafe. I agree it should never be used.

Amir Raminfar
  • 33,777
  • 7
  • 93
  • 123
  • There are a few CMS' out there, some regarded as 'popular', that use this technique. The 'view layouts', menus, etc are stored as php code in the database. It's often necessary to be able to change these bits of code (layouts, menu plugins, etc). I guess this is an alternative to making the theme files writable by the webserver which is what Wordpress, for example, does. But using eval just has horrible code smell. – user210179 Jan 25 '11 at 19:33
3

Yes, it can be very dangerous. One place I've seen it used was a system that allowed a very complex configuration of a search screen, and allowed users to save the search configs. The details of the search were saved as actual code that was executed as eval. The inputs were stored separately and were checked (to some degree, I don't know the details) to prevent against SQL injection. That's the only time I've seen that done, and it probably wasn't necessary (though I never saw enough of this system to know for sure).

eval() is potentially useful when you don't know what code will need to execute until runtime (like the example I gave above), but these cases are not the sort of thing that happen every day for most developers. If you ever do run into a situation where you need an eval(), just try to make sure you never directly pass it input from the user. Better still if you can find a way to constrain (to some degree) the code that will be passed in to it, but this will depend on the problem at hand.

FrustratedWithFormsDesigner
  • 26,726
  • 31
  • 139
  • 202
2

Could you please provide me some examples on how this eval() can be usefull?

It is used by template engines, for example. They parse and compile templates to PHP code, and can either store the code to any location, or execute it directly with eval().

Other than that, it is a dangerous feature.

Arnaud Le Blanc
  • 98,321
  • 23
  • 206
  • 194
  • Can you give an example template engine? – Jonah Jan 25 '11 at 18:38
  • I would say most of them; [Smarty](http://www.smarty.net/) and [Twig](http://www.twig-project.org/) do. – Arnaud Le Blanc Jan 25 '11 at 18:40
  • That's why i hate template engines. – Shoe Jan 25 '11 at 18:41
  • 2
    @Charlie Pigarelli: That's no reason to hate them. They use `eval` only as the last resort, if caching is disabled. And furthermore: If the code is properly checked against malicious code, there really isn't a problem using eval ;) – NikiC Jan 25 '11 at 19:22
  • Sorry, i should have pointed it out: That's also why, over thousands of non sense things, i hate templates engines like Smarty. I would never use them, even if `eval()` is not part of the script. Because they have no sense at all. You can do everything you do with your template engine with PHP itself (separating logic and view also), faster and without caching nothing. – Shoe Jan 25 '11 at 19:27
  • this is freaking unsafe regarding XSS ;-) – Arnaud Le Blanc Jan 25 '11 at 19:34
1

Well it is unsafe indeed, you have to sanitize your code anyways.

However it is not intended to evaluate expressions introduced by users or any other means such as from DB.

I've found it usefull when the language does not provide metaprogramming. So for example you need to fill a bean with 50 fields that are called the same but with a small difference in the method name such as a number (imagine it has field1(), field2(), field3() ... etc), then you can use the eval inside a for: construct the method name as a string and then call it.

This way you can convert 100 repetitive lines of code in 5, a couple more if you want to add documentation on how it works lol. It is not unsafe because nobody elses touches your code here.

htafoya
  • 18,261
  • 11
  • 80
  • 104
  • +1 despite indorsing the OPs subjective meme question and the vague and unimplementable "sanitize your code" phrase. Metaprogramming is indeed a valid use when closures are insufficient. – mario Jan 25 '11 at 19:01
  • 1
    could be rewritten as: $object -> $method (no need for eval at all) – Kamil Tomšík Jan 25 '11 at 19:33
0

You can have something like

$text = 'This is some random number: $number. Hello world!';
...
$number = 15;
...
eval ("\$replacedText = \"$text\";");

In the eval $text would be replaced by "This is some random number: $number. Hello world!", and eval makes sure that $number is also replaced by 15

vmpstr
  • 5,051
  • 2
  • 25
  • 25
  • 1
    what about [`str_replace`](http://php.net/str_replace) instead ? `$text = str_replace('$number', '15', $text);` does exactly the same thing. – Arnaud Le Blanc Jan 25 '11 at 18:33
  • @user576875: Or double-quotes? – Jonah Jan 25 '11 at 18:34
  • I think i'm missing something. `$number` is never replaced into a string with single ('). Is it? – Shoe Jan 25 '11 at 18:35
  • @Jonah, Here in Italy it's evening and i'm tired and probably more stupid than usually, but I don't see any point on creating a problem and solve it with `eval()`. – Shoe Jan 25 '11 at 18:40
  • @Charlie: I agree. I wasn't defending the answer, just explaining it (however ludicrous it is). The "???" was pointed at the answer, not you ;) – Jonah Jan 25 '11 at 18:41