tags:

views:

67

answers:

4

Hi!

I would like to know how to test if system() or exec() is allowed on a server. I keep getting this error "Warning: exec() has been disabled for security reasons in ..."

I understand that the safe_mode function is depreciated in the php version my provider runs (5.3.3) so i cant use a get_ini('safe_mode') check.

What else to do?

I use this for a backup script. if the provider allows system, the script makes a tar file and mails it to me whenever a user logs in.

Thanks in advance.

A: 

function_exists() doesn't works for this situation ?

http://fr.php.net/function_exists

Frosty Z
Nope. It's a core function, so it will always exist.
ircmaxell
no. in my test function_exists() and is_callable() both returned true. Which i can believe because exec and system both are valid function names and callable.
half-a-nerd
If they returned false, it would open the door to hosts (or attackers, etc) re-defining them and then sniffing for sensitive data (or worse)...
ircmaxell
A: 

exec() returns false if it fails, or a success message string if it succeeds... so the following should work:

if(!exec('cd .')){ die('ERROR: Exec is not available!!!"); }

Replacement for 'cd .' can be any function you know to work on the system.

vdoogs
edited with cd . per discussion above.
vdoogs
+4  A: 

Well, there's only two ways it can be disabled: safe_mode or disable_functions.

So you can do a check like:

function isAvailable($func) {
    if (ini_get('safe_mode')) return false;
    $disabled = ini_get('disable_functions');
    if ($disabled) {
        $disabled = explode(',', $disabled);
        $disabled = array_map('trim', $disabled);
        return !in_array($func, $disabled);
    }
    return true;
}

Oh, and function_exists should return true, since it's a core function (otherwise you could forge a core function and cause some real havoc on a host)... Therefore is_callable should also return true (since the function does exist). So the only ways to tell, are to check the ini settings, or to actually call it...

Edit: One other thing to note, there are several of ways to execute shell commands. Check out:

ircmaxell
Is this done using `disable_function()` though? Because what the OP talks about also disables backticks.
Pekka
@Pekka: The only two directives that I know of that effect `system()` and `exec()` are `safe_mode` and `disable_functions`. So if it's not one, it must be the other. And if it's neither, it should work...
ircmaxell
@ircmaxell true, I can't find any other way, either. But does that mean that backticks remain enabled even if I disable `exec()`? Can't test right now, maybe later...
Pekka
@Pekka: Yes. The backticks are just a [language level alias](http://us2.php.net/manual/en/language.operators.execution.php) of `shell_exec`. So they are available as long as `shell_exec` is (but if you add `shell_exec` to `disable_functions`, they will stop working)...
ircmaxell
@ircmaxell ah, good to know! Thanks. One argument for actually trying to execute a command is if you want to be sure there is nothing else blocking execution (e.g. the [Suhosin](http://www.hardened-php.net/suhosin/) patch). If that is not an issue, this is the easiest way to go. +1
Pekka
You are absolutely spot on with this function. THANKS.
half-a-nerd
The only thing is that this function returns true if the function is found in the disabled list. so you would want this function to return false in stead. so i changed the return in_array funtion into if(in_array(...)) return false;
half-a-nerd
@half-a-nerd: I spotted that error and edited it a little while ago to `return !in_array(...)`. But nice spot either way...
ircmaxell
+3  A: 

Testing for disabled functions and the presence of safe mode as shown by @ircmaxell is arguably the easiest way to go.

If you want to find out 1000% reliably whether execution of system commands is possible - there may be security patches like Suhosin that block this on another level - try to exec() an external command that is bound to work on all systems (including Windows), and is extremely unlikely to fail even if user rights are very tight.

Say

cd .   

this should work (i.e. not return false, and return an error level code of 0) at least on all Linux, Windows and Unix flavours including OS X.

Pekka
Since both Linux and Windows have the `cd` command, `exec('cd .')` might be the best bet (it has no side effect, and should work on all systems)... Otherwise, +1...
ircmaxell
@ircmaxell that's even better, good idea!
Pekka