开发者

How to check an exectuable's path is correct in PHP?

开发者 https://www.devze.com 2023-01-02 11:32 出处:网络
I\'m writing a setup/installer script for my application, ba开发者_JAVA百科sically just a nice front end to the configuration file. One of the configuration variables is the executable path for mysql.

I'm writing a setup/installer script for my application, ba开发者_JAVA百科sically just a nice front end to the configuration file. One of the configuration variables is the executable path for mysql. After the user has typed it in (for example: /path/to/mysql-5.0/bin/mysql or just mysql if it is in their system PATH), I want to verify that it is correct. My initial reaction would be to try running it with "--version" to see what comes back. However, I quickly realised this would lead to me writing this line of code:

shell_exec($somethingAUserHasEntered . " --version");

...which is obviously a Very Bad Thing. Now, this is a setup script which is designed for trusted users only, and ones which probably already have relatively high level access to the system, but still I don't think the above solution is something I want to write.

Is there a better way to verify the executable path? Perhaps one which doesn't expose a massive security hole?


Running arbitrary user commands is like running queries based on user input... Escaping is the key.

First, validate if it is an executable using is_executable().

PHP exposes two functions for this: escapeshellarg() and escapeshellcmd().

escapeshellarg() adds single quotes around a string and quotes/escapes any existing single quotes allowing you to pass a string directly to a shell function and having it be treated as a single safe argument.

escapeshellcmd() escapes any characters in a string that might be used to trick a shell command into executing arbitrary commands.

This should limit the amount of risk.

if(is_executable($somethingAUserHasEntered)) {
  shell_exec(escapeshellarg($somethingAUserHasEntered) . " --version");
}

After all, doing rm --version isn't very harmful, and "rm -rf / &&" --version will get you anywhere very fast.


EDIT: Since you mentioned PATH... Here is a quick function to validate if the file is an executable according to PATH rules:

function is_exec($file) {
  if(is_executable($file)) return true;
  if(realpath($file) == $file) return false; // Absolute Path

  $paths = explode(PATH_SEPARATOR, $_ENV['PATH']);

  foreach($paths as $path) {
    // Make sure it has a trailing slash
    $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
    if(is_executable($path . $file)) return true;
  }

  return false;
}


You could try a simple file_exists call to determine if something exists at that location, along with an is_executable to confirm that it's something you can run.


have you looked at is_dir() or is_link() or is_file() or is_readable()

Hope these help.


system('which '.escapeshellarg($input)) will give you the absolute path to the executable, regardless if it's just the name or an absolute path.

0

精彩评论

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

关注公众号