Manual:Shell framework

From MediaWiki.org
Jump to navigation Jump to search
MediaWiki version: 1.30
Gerrit change 319505

MediaWiki provides a robust framework for shelling out to external commands for increased performance, security, and portability. See the documentation for Shell and Command. A basic example:

use MediaWiki\Shell\Shell;
use MediaWiki\Logger\LoggerFactory;

$result = Shell::command( '/usr/bin/command' )
    ->environment( [ 'VAR' => 'VALUE' ] )
    ->limits( [ 'time' => 300 ] )
    ->execute();

$exitCode = $result->getExitCode();
$output = $result->getStdout();
$error = $result->getStderr();

This replaces the wfShellExec() global function, which is deprecated since MediaWiki 1.30, in favor of this new shell framework.

Parameters[edit]

Most of the time you'll also want to provide some parameters to the command. MediaWiki will automatically escape all parameters to prevent shell injection attacks:

$command = Shell::command( 'command', '--path' , $somePath );

In the rare case you need to pass a parameter unscaped, you can use:

$command = Shell::command( 'command' )->unsafeParams( '-x -y -z' );

You can use Shell::escape to manually escape parts of an unescaped parameter.

Limits[edit]

For both performance and security reasons, MediaWiki institutes limits on CPU time, wall clock time, file size and the memory usage a command can use. The defaults from $wgMaxShellTime, $wgMaxShellWallClockTime, $wgMaxShellMemory, and $wgMaxShellFileSize will be used unless overriden with a call to ->limits(...).

Further restrictions can be implemented using cgroups, see $wgShellCgroup for more details.

Restrictions[edit]

MediaWiki version: 1.31
Gerrit change 384930

Since 1.31, MediaWiki supports sandboxing commands with external restriction software - currently only firejail is supported, and must be enabled with $wgShellRestrictionMethod. You can pass any of the following constants to ->restrict(...):

  • Shell::RESTRICT_DEFAULT - a convenience constant equivalent to NO_ROOT | SECCOMP | PRIVATE_DEV | NO_LOCALSETTINGS
  • Shell::NO_ROOT - Disallow any root access. Any setuid binaries will be run without elevated access.
  • Shell::SECCOMP - Use seccomp to block dangerous syscalls.
  • Shell::PRIVATE_DEV - Create a private /dev
  • Shell::NO_LOCALSETTINGS - Deny access to LocalSettings.php, which likely contains database passwords and other secrets.
  • Shell::NO_NETWORK - Disallow any network access.
  • Shell::NO_EXECVE - Deny the execve syscall with seccomp (basically preventing the program from calling other executables). Shell::SECCOMP must also be set.

You can look at the restriction of binaries in the Score extension as an example.

firejail profile[edit]

MediaWiki uses a firejail profile that allows for extra customization and restrictions depending upon your platform. Create /etc/firejail/mediawiki.local (syntax) to restrict other paths that might have secret information, e.g.:

# MediaWiki local firejail additions
blacklist /srv/private

See Wikimedia's mediawiki.local as an example.

Logging[edit]

By default, errors and standard error output are logged to the exec channel in a structured form. A different logger can be set via the standard PSR-3 LoggerAwareInterface.