Content:
The eval()
function in PHP allows a string to be executed as a piece of code. eval
, short for evaluate, takes a string as an input and executes the string as a block of code.
On the face of it, the eval()
function appears quite useful. Dynamically generating code can make an application more flexible.
But the functionality it provides can prove incredibly dangerous, and it is not recommended to use it unless it’s absolutely necessary.
In fact, this is what the founder of the PHP language had to say:
“If `eval()` is the answer, you’re almost certainly asking the wrong question.”
Rasmus Lerdorf, PHP Founder
In this article, we’ll take a look at why eval()
is so dangerous.
Malicious Inputs
Allowing the execution of data from arbitrary sources is a recipe for disaster, with the potential for an attacker to gain full control of your server.
When eval()
evaluates a string, it has the same effect as running code in a file.
eval($_GET['input']);
Consider the effect of a user themselves typing valid code into an input. In this example, the input is "'';echo system('dir');"
eval($_GET['input']) # "'';echo system('dir');"
eval("echo " . $_GET['input']) # file1.php file2.php ...
eval()
takes this input string, and runs it. The code entered by the user is now executed. Anyone familiar with SQL injection attacks will see the similarity here, as the concept is identical.
The code echo system('dir')
passed by the user is executed, and a list of files in the current directory will be printed.
Whatever permissions the web server user has over the system, will be in the hands of the attacker. This includes OS-level functionality, such as deleting files. Combined with exec()
, pretty much any command to be executed, in any language supported on the server.
As a rule, you should never trust a user’s input. This holds regardless of how clean you expect the input to be.
Alternatives
To avoid using eval()
, you should create functions to properly parse the input from the user.
Consider matching the input to a known set of good values, that are hard-coded in your application. Using values you’ve defined is much safer, as you can be sure the resulting value is not malicious.
Replicate the functionality intended in the eval()
using separate functions. Rather than relying on crafting strings to run code, pass the input values to proper functions designed to serve the same purpose.