Avoiding EVAL()

There are a shed-load of ways to “eval()” code without actually calling the eval() function — usually done simply to avoid the use of the dreaded “evil()” function, but often times because the system has eval() disabled using “disable_functions” in php.ini

Here is another simple way to avoid eval() without writing out files to the filesystem etc:

<?php
$code = '<?php echo "Hello World"; ?>;
include('data:text/plaintext;base64,' . base64_encode($code));
?>

This uses the new data: stream wrapper (RFC2397) that was introduced with PHP 5.2.0; and while this seems like a risk, first: The “attacker” already has access to the code on your system, or you’re open to injection anyway, second: PHP 5.2 has also fixed the problem with the introduction of the  ”allow_url_include” php.ini option.

I just thought it was a neat little streams “hack” I would share; I originally thought to do it using the var stream from PHP’s stream_wrapper_register() documentation, but then Evert Pot posted about creating streams from strings using the data: stream, which led to this final “solution”.

- Davey

12 Responses to “Avoiding EVAL()”

  1. gasper_k says:

    Nice piece of information, thanks. However, I think either you’re wrong or I understood you wrong, but allow_url_include directive has been available since 5.1.

  2. allow_url_include is no 5.3 but 5.2 introduced feature, data: was no “URL Stream” for one or two versions of that series, but that was fixed soon to avoid troubles like the one above :-)

  3. Andrei says:

    Silly and completely useless. I don’t see an serious use case for this “feature”.

    • Davey Shafik says:

      I never claimed it was useful. And there certainly is no *serious* use case; I just enjoy bending the language :)

      • EllisGL says:

        There’s a lot of pay scripts that are eval base64 encoded.. Could use this to no use eval.. Still insecure.

  4. Timothy says:

    man… and I thought I wrote sinister code! Thanks for sharing, Davey.

  5. Matt says:

    Lookie:

    http://pastebin.com/f6662eb57

    eval() is significantly faster than include() – on my computer it’s a difference of about 35%.

    • Davey Shafik says:

      This is quite obvious; there is a base64_encode() and a base64_decode() involved in my solution. However, benchmarks in userland are inherently flawed.

  6. Žilvinas says:

    On the other hand this shows a nice exploit when eval is disabled. You could easily inject your code to execute by exploiting a bug with dynamic variable includes.

Twitter

@dshafik Anytime tools are released that give just anyone the ability to do something without coding, programmers see a pay cut in contracts

@fasterkitty [2 hours ago]

@fasterkitty I think that depends on the quality of the apps the Flash folks put out...

@dshafik [2 hours ago]

@fasterkitty from what I hear, they are already culling apps that violate the Desktop/Widget rule. For example: http://bit.ly/cb3l0B

@dshafik [2 hours ago]

Looking for a design, thinking of using 99designs; unless someone I know wants to do some work for me? (for pay!)

@dshafik [3 hours ago]

@dshafik can you please call our support, so that we could help you with those issues?

@EyeFiCard [6 hours ago]

Books & Things