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
精彩评论