Manual:Shell framework
MediaWiki version: | ≥ 1.30 Gerrit change 319505 |
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
editMost 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
editFor 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
editMediaWiki version: | ≥ 1.31 Gerrit change 384930 |
Deprecated: This feature is deprecated and should no longer be used, however it is still available for reasons of backwards compatibility .
|
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
editMediaWiki 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
editBy 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
.