Manual:Shell framework

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 overridden 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.