Manual:Shell framework
<translate> MediaWiki version:</translate> |
While not explicitly deprecated, it is recommended to use BoxedCommand (Shellbox) in new code for increased compatibility with running in containers and better security features. |
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
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
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
<td class="mw-version-versionbox" title="<translate nowrap> The latest stable version is <tvar name=1>1.41</tvar></translate>"><translate> MediaWiki version:</translate> |
File:OOjs UI icon alert-destructive.svg | <translate>
This deprecated feature should no longer be used, but is still available for reasons of backwards compatibility. This feature was deprecated in version <tvar name=ver>1.38</tvar>.</translate> <translate> Please see <tvar name=page>BoxedCommand</tvar> for an alternative way to use this feature.</translate> |
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 toNO_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
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
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
.