开发者

How can I disable the 'e' PREG_REPLACE_EVAL modifier in PHP?

I want to know how to disable the eval modifier in PHP's regex system eg. preg_replace('/.*/e', $code, '.'). It's a potential exploit that can be used in place of eval if anyone manages to get dodgy code onto a server. I had a problem recently with a wordpress theme from woothemes that had a security hole that allowed hackers to upload a back door server admin type script.

开发者_运维问答

I have this in my php.ini:

disable_functions = eval

Which prevented most of the damage that could've been done but I was wondering if I can do something similar to prevent all forms of 'eval' apart from the call_user_func_array() stuff?


The Suhosin extension provides an option to disable the /e modifier.

disable_functions = eval by the way won't do what you expect (as eval is not a function, but a language construct). Again the Suhosin extension provides an option to disable eval.


find & replace ? :)

No you cannot disable a specific functionality of a specific function.

What you can do however, is to keep your server updated & protected. You may try to run the apache process within a chroot, limit the used resources, install a firewall, etc... you can find lots of tutorials on how to secure your linux installation on the net.

I found these related to wordpress, seems like a bunch of sane tips:

  • http://wp.tutsplus.com/tutorials/security/20-steps-to-a-flexible-and-secure-wordpress-installation/
  • http://codex.wordpress.org/Hardening_WordPress


To remove the modifier "e" from regular expressions (for example, if the user has access to setting regular expressions in applications), I wrote a function to cut out the modifier "e" from any regexp pattern.

function remove_emodifier($pattern)
{
    $pattern_parts = explode($pattern{0}, trim($pattern));
    $pattern_last = sizeof($pattern_parts) - 1;
    $pattern_parts[$pattern_last] = str_replace('e', '', $pattern_parts[$pattern_last]);

    return implode($pattern{0}, $pattern_parts);
}

echo preg_replace('/^(.*)$/iex', 'strrev("\\1")', 'my_string'); // gnirts_ym
echo preg_replace(remove_emodifier('/^(.*)$/iex'), 'strrev("\\1")', 'my_string'); // strrev("my_string")

echo remove_emodifier('|abc|eix'); // |abc|ix
echo remove_emodifier('#.+(\d+)#iseU'); // #.+(\d+)#isU


The Diseval PHP extension will also disable the /e modifier in both php5 and php7 while at the same time disabling eval: https://github.com/mk-j/PHP_diseval_extension

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜