The Dangers of Using PHP’s eval() Function: Risks and Secure Alternatives

The Dangers of Using PHP’s eval() Function: Risks and Secure Alternatives
The Dangers of Using PHP’s eval() Function: Risks and Secure Alternatives

Learn the dangers of PHP's eval() function and how to prevent vulnerabilities through secure alternatives and best practices.

Most PHP backdoors we clean off hacked WordPress sites share one line: eval(). It hands attackers a way to run whatever code they can smuggle in, and it hides in plain sight. So before you reach for it, know exactly what you’re signing up for.

eval() takes a string and runs it as PHP. That’s the whole feature. It’s also the whole problem. Below we’ll walk through what it does, where it goes wrong, and what to use instead.

Table of Contents

What is PHP’s eval() Function?

eval() evaluates a string as PHP code. You pass it a string, PHP compiles it, and runs it as if you’d typed it into your source file. If any part of that string comes from input you don’t fully control, you’ve just given that input the run of your server.

One detail worth knowing: eval() is a language construct, not a real function. That’s not trivia. It means you can’t turn it off with the disable_functions setting in php.ini the way you’d block exec or system. Your only real defense is not to use it.

Here’s the simplest possible example:

Example of the code
PHP
<?php
$code = 'echo "Hello, World!";';
eval($code);

The string $code goes into eval(), and it prints “Hello, World!” like any other line of PHP. Harmless here, because you wrote the string. The moment that string carries anything a user typed, the same mechanism becomes a loaded gun.

The Risks of Using eval()

Here’s what you’re actually risking every time eval() touches data you didn’t write yourself:

  • Remote code execution: This is the big one. Feed eval() any untrusted input and an attacker can run arbitrary PHP on your server. Not “maybe leak a value.” Full code execution, which is as bad as it gets.
  • Arbitrary actions: Because it runs any PHP, injected code can read or wipe files, dump your database, and drop a backdoor to come back later.
  • You can’t disable it: As above, disable_functions won’t help. There’s no per-project off switch built into PHP.
  • Slower and harder to debug: Every call recompiles the string, so it skips the opcode cache that keeps normal code fast. And since the logic only exists at runtime, your editor, linter, and stack traces can’t see it. When it breaks, you’re mostly guessing.

Add it up and the honest position is simple: avoid eval(). If you think you need it, you almost certainly have a cleaner option, and we’ll get to those.

How Code Injection and Execution Happens

The classic mistake is passing user input straight into eval(). It looks convenient. It’s a wide-open door:

Example of the code
PHP
<?php
$user_input = $_GET['code'];
eval($user_input);

Now anyone can send PHP through the code parameter in the URL. Start small:

http://example.com/page.php?code=phpinfo();

That runs phpinfo() and hands over your full server config, which is a gift to an attacker mapping their next move. Swap in code that writes a file or queries your database and it stops being reconnaissance and starts being a breach.

From that one line, an attacker can:

  • Steal data: run queries that pull sensitive records straight out of your database.
  • Compromise the system: read, modify, or plant files on the server.
  • Take full control: chain it into complete remote code execution and own the box.

Real-World Examples of eval() Vulnerabilities

This isn’t theoretical. It shows up constantly in the wild:

  • WordPress plugins: plugins have shipped eval() on unsanitized input, letting attackers inject and run code on every site that installed them.
  • Malware backdoors: compromised sites are riddled with eval(), usually wrapped in base64 or gzip to dodge scanners. It’s a favorite exactly because it runs anything and hides well.

When we clean an infected site, an obfuscated eval() is often the first thing we grep for. That should tell you how the pros treat it.

Secure Alternatives to eval()

Almost every real reason people reach for eval() has a safer answer. Match your case to one of these:

  • Parsing data, not code: if you’re evaluating a string that’s really just data, use the right parser. json_decode() for JSON is the common one. Never eval() a payload to “turn it into” an array.
  • Calling a function by name: use call_user_func() or call_user_func_array(). They call a function chosen at runtime without evaluating raw code, and you can check the name against an allowlist first.
  • Branching on input: a switch statement or a whitelisted lookup map (input maps to one of a fixed set of outcomes) is safer and easier to read than building code strings.
  • Generating dynamic output: use a templating engine like Twig or Blade. It keeps logic out of your markup without running arbitrary PHP.

The through-line: decide the allowed behaviors in advance and map input onto them. Don’t let input become the code.

Conclusion

eval() runs arbitrary PHP, and the second untrusted input reaches it, that’s remote code execution. You can’t even switch it off in config. For nearly everything people use it for, there’s a cleaner tool that does the job without the blast radius.

So the rule is easy to remember: don’t use eval(), especially anywhere near user input. Reach for json_decode(), call_user_func(), a switch, or a real templating engine instead, and keep the door shut.

Leave a Comment

Your email address will not be published. Required fields are marked *


Scroll to Top