1

I'm having a problem with PHP disable_functions. In a Apache Server running suPHP FastCGI PHP > 5.3.0 I'm trying to set the disable_functions value per virtualhost. To do so what I'm doing is disabling in suPHP configuration the use of suPHP_ConfigPath to disallow users from using their own php.ini file. Then in the global php.ini file I use the php sections [PATH] directive to configure a custom disable_functions on a specific virtualhost. Something like:

php.ini file

...
disable_functions = shell_exec, exec

[PATH=/home/someuser/public_html]
disable_functions =
...

If I check php configuration in that virtualhost with a phpinfo file I get the correct expected values. Disable_functions directive has a local value = no value and a master value = shell_exec, exec. But if I run a test script that uses shell_exec the server blocks it showing an error that indicates that shell_exec has been disabled for security reasons. This means PHP is ignoring disable_functions local value and using the master value instead.

I'm not able to figure out why that doesn't work as expected as for the [PATH] [HOST] PHP sections documentation should be possible to configure disable function on those sections. Only extension and zend_extension directives should not be used in sections as for the documentation.

I have already tested with other directives PHP_INI_SYSTEM and even a php.ini only directive (expose_php) and all have worked as expected. So I'm totally lost and I can't understand what's going on.

Just for completeness I have tested in a Apache Server running FastCGI + SuExec PHP > 5.3.0 (similar configuration than suPHP but not exactly the same) and same thing happen, disable_functions local value is ignored.

Anyone knows a good reason why this is not working? Is it a PHP bug? Is there something I'm not taking into account?

5
  • "This means PHP is ignoring disable_functions local value and using the master value instead." -- are you sure it doesn't mean that it's appending extra functions? Try adding a third function for the PATH, and see if it gets disabled too. Commented Jun 25, 2013 at 18:57
  • Makes no sense at all. Why should disable_functions work by adding and all the rest of directives work by overriding value?. Anyway I did the test by just configuring the local value = shell_exec with the PATH section and the master value = exec by removing the shell_exec in the global configuration. As expected with that configuration shell_exec works because master value now only blocks exec function confirming that the local value is ignored. Commented Jun 25, 2013 at 19:04
  • Heh, don't ask me why it would make sense. It's PHP. :-P I'd suggest asking this in the bug tracker. Perhaps there are some undocumented internals that might explain the behavior. Come to think of it, in fact, that is quite likely. I'd be surprised if mod_php can conditionally disable a function based on the path -- intuitively, it would seem a bit gory to enforce. Perhaps try setting things up with a local php.ini file instead, since you're using fastcgi? Commented Jun 25, 2013 at 19:45
  • Firstly I want to clarify, don't get me wrong I appreciate the attempt to aid. But even being PHP there is always a reason. And that's the reason I'm looking for. There is a specific documentation about PHP sections [PATH] and [HOST] and we should expect PHP working the way the documentation specifies. If not then there is a bug on documentation or on implementation because if they don't match there is a mismatch between doc, implementation and design. The module is mod_suphp which runs PHP as a CGI script. Commented Jun 27, 2013 at 22:37
  • As I said in my previous comment, I'd suggest asking in the php bug tracker... Commented Jun 27, 2013 at 22:55

1 Answer 1

2

It's clearly stated in PHP Manual that disable_functions can only be set in the master php.ini. Local values can be set and are visible with phpinfo(), but don't seem have any effect (at least on PHP 5.5).

To work this around, I use per-vhost auto_prepend_file (or one global with per-vhost sub-includes). The script included calls uopz_delete(). If uopz PECL extension isn't available for your PHP version or OS, etc. you can try other extensions like APD or runkit, as they have similar functions to delete/cloak other PHP functions.

The solution with uopz has been tested on a few production servers running Ubuntu with PHP 5.5.9. It doesn't seem to affect performance heavily, nor to cause any instability.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.