Last modified: 2011-08-19 22:24:03 UTC

Wikimedia Bugzilla is closed!

Wikimedia has migrated from Bugzilla to Phabricator. Bug reports should be created and updated in Wikimedia Phabricator instead. Please create an account in Phabricator and add your Bugzilla email address to it.
Wikimedia Bugzilla is read-only. If you try to edit or create any bug report in Bugzilla you will be shown an intentional error message.
In order to access the Phabricator task corresponding to a Bugzilla report, just remove "static-" from its URL.
You could still run searches in Bugzilla or access your list of votes but bug reports will obviously not be up-to-date in Bugzilla.
Bug 3891 - math.php is not compatible with php safe_mode, fix enclosed
math.php is not compatible with php safe_mode, fix enclosed
Product: MediaWiki extensions
Classification: Unclassified
Math (Other open bugs)
All All
: Lowest normal (vote)
: ---
Assigned To: Nobody - You can work on this!
Depends on:
  Show dependency treegraph
Reported: 2005-11-06 11:46 UTC by Dan Hollis
Modified: 2011-08-19 22:24 UTC (History)
1 user (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---

Work in progress: wfShellExec() wrapper (9.57 KB, patch)
2005-11-09 03:24 UTC, Brion Vibber

Description Dan Hollis 2005-11-06 11:46:49 UTC
math.php is not compatible with php safe_mode.

                        $contents = `$cmd`;
                        wfDebug( "TeX output:\n $contents\n---\n" );

using backticks is forbidden in safe_mode:

PHP Warning:  shell_exec(): Cannot execute using backquotes in Safe Mode in
/var/www/wiki/public_html/includes/Math.php on line 75

please consider using popen() instead. it is easy to do and compatible with

$phandle = popen( $cmd );
$contents = fgets( $phandle );
fclose( $phandle );
Comment 1 Brion Vibber 2005-11-06 19:48:05 UTC
safe_mode is not supported; additionally a configuration with 
safe_mode is likely to use half a dozen other broken 
configuration items such as disabling of these functions.
Comment 2 Dan Hollis 2005-11-07 01:34:19 UTC
it is perfectly simple and trivial to repair currently broken math.php so it
runs perfectly fine in safe_mode, you are stating that it is mediawiki's
official policy to refuse to do such things even when it is trivial?

this fix breaks _absolutely nothing_ for non-safemode, and makes it _work_ in
safe_mode. so what's the problem?
Comment 3 Rob Church 2005-11-07 02:34:41 UTC
There isn't necessarily a problem in this particular case, but in other
instances, MediaWiki relies upon things which are disabled under safe mode, or
which may well be broken - Brion's point is that if safe mode is on, then a
number of other configuration options might be set within PHP or even the web
server software, which would produce incompatibilities with MediaWiki.
Comment 4 Brion Vibber 2005-11-07 02:38:17 UTC
A safe_mode configuration will most likely have other program execution 
functions also disabled (and if it doesn't, it's a very poor excuse for 
a "safe" configuration, as popen etc allow you to do everything that 
backticks can do!)

So there wouldn't seem to be much point to this, would there?

If you don't require safe_mode, turn it off. If you do, but your 
suggestion works, then your safe_mode is itself broken and isn't 
protecting you. (And various other things also may break, as we don't 
support safe_mode.)

I recommend you submit a patch to PHP to treat backticks with the same 
permission level as other shell-out methods.
Comment 5 Dan Hollis 2005-11-07 03:19:21 UTC
i don't quite get this digging-in-heels attitude from you brion. this patch
breaks nothing and makes it work in safe_mode.

math.php can get changed far easier than getting PHP to "fix" safe mode.

ok, you have ideological issues with PHP safe mode. fine. it might be broke on
some sites. fine.

however not all of us running mediawiki in safe_mode are complete idiots running
broken servers, please don't treat us as such.

it is quite easy to run mediawiki in safe_mode with few problems (other than
uploads). other extensions and plugins can be made to cleanly and easily and
simply work in safe_mode without any problems at all (for example, graphviz).

is it so outrageous to accomodate us with this tiny change that breaks
absolutely nothing for those not running in safe_mode? or is ideology going to
win out? i might have expected this kind of response from TDR or DJB, do we have
a budding new candidate here?
Comment 6 Brion Vibber 2005-11-07 03:27:16 UTC
Can you provide some details of your configuration? (PHP version, any 
other disabled/enabled functions, safe_mode_exec_dir, open_basedir etc). 
Just want to check if there's any other fun surprises, and if we can/
should make similar change elsewhere in the code.

(I *do* recommend trying to get PHP fixed, independently of any changes 
that may be made to MediaWiki. Inconsistency between shell_exec and 
popen seems kind of odd when they already have the infrastructure for a 
safe_mode_exec_dir. That doesn't mean we can't make a tweak here to 
accommodate it, and this bug has *not* been closed WONTFIX.)
Comment 7 Dan Hollis 2005-11-07 04:38:27 UTC
php 4.3.11
apache 2.0.53
linux 2.6.14+grsec+pax (

safe_mode = On
safe_mode_gid = Off
safe_mode_include_dir = 
safe_mode_exec_dir = /usr/local/bin/php_safe_mode_exec_dir
safe_mode_allowed_env_vars = PHP_
safe_mode_protected_env_vars = LD_LIBRARY_PATH
disable_functions =
disable_classes =

(yes, php sucks. yes, shell_exec, popen, etc inconsistency makes no sense. true.

yes, safe_mode is imperfect. it doesn't protect against _everything_. true.

what safe_mode does prevent is script kiddies coercing php into doing `wget` because you can prevent wget from being executed.
and this is the most common exploit i've seen on PHP. safe_mode closes it.

does safe_mode close all avenues of attack? no. nothing does, short of encasing
your PC in 20 tons of concrete and sinking it to the bottom of the mariana trench.

what safe_mode does do is make mediawiki somewhat more acceptable to large
shared hosting services, and that can only be a good thing.

and yes, i'll pressure the PHP devs to fix safe_mode.)
Comment 8 Brion Vibber 2005-11-07 07:16:03 UTC
Quick survey of usage grepping around:

shell_exec won't work under safe_mode:
./includes/Image.php:                           $conv = shell_exec( $cmd );
./includes/Image.php:                   $conv = shell_exec( $cmd );

`` is equivalent to shell_exec and won't work under safe_mode:
./config/index.php:                     if (strstr(`$file`, $versioninfo[1]) !== 
./includes/Math.php:                    $contents = `$cmd`;
./includes/MimeMagic.php:                       $m= `$wgMimeDetectorCommand $fn`;
./includes/proxy_check.php:     $host = trim(`hostname`);
./maintenance/          $diff = `diff -au $infile $outfile`;

popen should work, subject to safe_mode_exec_dir:
./includes/Export.php:          $this->handle = popen( $command, "w" );
./includes/GlobalFunctions.php: $handle = popen( $cmd, 'r' );
./includes/GlobalFunctions.php: $handle = popen( $cmd, 'r' );

Docs don't specify about proc_open.
./includes/Parser.php:          $process = proc_open("$wgTidyBin -config $wgTidyConf 
$wgTidyOpts$opts", $descriptorspec, $pipes);

There's this warning on docs for system() and popen():
"With safe mode enabled, all words following the initial command string are treated 
as a single argument. Thus, echo y | echo x becomes echo "y | echo x"."

Hopefully that's not actually true, or I don't think anything we shell out to would 
Comment 9 Brion Vibber 2005-11-07 07:39:30 UTC
Also exec() and passthru(), which understand safe_mode and safe_mode_exec_dir:
./includes/Database.php:                        exec( "php $IP/includes/killthread.php 
$timeout $tid &>/dev/null &" );
./includes/DatabaseOracle.php:          exec( "php $IP/killthread.php $timeout $tid 
&>/dev/null &" );*/
./includes/DatabasePostgreSQL.php:              exec( "php $IP/killthread.php $timeout 
$tid &>/dev/null &" );*/
./includes/ParserXML.php:               exec($html2xml.' < '.$tmpfname, $a);
./includes/ParserXML.php:               exec($wgWiki2xml.' < '.$tmpfname, $a);
./includes/ProxyTools.php:                      exec( "php $params &>/dev/null &" );
./includes/SpecialUpload.php:           if (wfIsWindows()) exec("$scanner",$output,
./includes/SpecialUpload.php:           else exec("$scanner 2>&1",$output,$code);
./maintenance/lang2po.php:      exec( XGETTEXT_BIN
./maintenance/lang2po.php:      exec(MSGMERGE_BIN.MSGMERGE_OPTIONS." $from $pot -o 
$dest ");

./maintenance/dumpHTML.php:                     passthru( "php dumpHTML.php -d " . 
wfEscapeShellArg( $dest ) . " -s $chunkStart -e $chunkEnd" );


Some quick testing (under PHP 5.1.0RC4) indicates that the documentation comment is 
TOTALLY FALSE. Separate arguments do get passed, with spaces and quotes separating 
them as expected, with all the above functions.
Comment 10 Dan Hollis 2005-11-07 08:01:55 UTC
./includes/proxy_check.php: $host = trim(`hostname`);

i have to wonder if there isn't a better way to do this. not to mention it won't
work on win32 without cygwin (ick).

i wonder if a lot of this stuff can't be cleaned up.
Comment 11 Zigger 2005-11-07 10:23:52 UTC
(In reply to comment #10)
> ./includes/proxy_check.php: $host = trim(`hostname`);
> i have to wonder if there isn't a better way to do this. not to 
mention it won't work on win32 without cygwin (ick).
> i wonder if a lot of this stuff can't be cleaned up.

There probably are better ways to do things, and this particlar output 
is for display purposes only, but a subset of hostname is a standard 
application on Windows 2000, XP (Professional edition at least), and 
2003.  Microsoft references include:
Comment 12 Dan Hollis 2005-11-07 11:17:04 UTC
i meant a standard way of doing it in php, instead of spawning external
executables. there is after all dns lookup facilities in php.
Comment 13 Brion Vibber 2005-11-09 00:29:02 UTC
popen() in safe mode *does* appear to be misapplying escaping rules.

I'm testing this math code:

It calls this command line:
/opt/safe/debug '/home/brion/src/wiki/rel1.5/images/tmp' '/home/brion/src/wiki/
rel1.5/images/tmp' '\frac{123}{456}' 'utf-8'

Calling texvc returns 'S', for syntax error. Calling a little debug script I can see 
that the parameters are misescaped:

import sys
for arg in sys.argv: print arg

shows output:

Turning safe_mode back off I get the expected output:

Testing with PHP 4.4.0 (Ubuntu Breezy packages).

Dan, did you test this? Does it work with your system or do you also end up with 
escaping failures?
Comment 14 Dan Hollis 2005-11-09 00:35:28 UTC
yes I got S (syntax error), so it needs more work. i didn't dig down enough to
see escaping failures.

the graphviz extension writes commands to a file then tells dot to read from the
file, perhaps the same could be done here?
Comment 15 Dan Hollis 2005-11-09 00:37:02 UTC
this also brings up a point, could someone exploit the math plugin in
non-safemode to execute arbitrary shell commands? since it backticks out to a
Comment 16 Brion Vibber 2005-11-09 01:49:57 UTC
Not unless there's a bug in escapeshellarg().
Comment 17 Brion Vibber 2005-11-09 02:29:13 UTC
I've filed a bug on the inaccurate documentation:
Comment 18 Brion Vibber 2005-11-09 03:24:49 UTC
Created attachment 1053 [details]
Work in progress: wfShellExec() wrapper

In progress patch: adds wfShellExec() wrapper which calls popen() when in safe
mode. Also adds a compatibility implementation of stream_get_contents() (handy
new function in PHP 5).

Doesn't fully work yet as popen() corrupts program arguments in safe mode.
Comment 19 Dan Hollis 2005-11-13 01:33:35 UTC
this seems relevant: safe_mode is going away.

however a good framework for executing commands would still be useful.
Comment 20 Brion Vibber 2006-06-04 00:30:08 UTC
Marking this LATER. The execution functions under safe mode are just
too broken to actually get anything done with them as is.
Comment 21 Max Semenik 2011-08-19 20:03:17 UTC
General consensus is that we don't really care about supporting ill-concieved deprecated features.
Comment 22 Dan Hollis 2011-08-19 22:24:03 UTC
and it only took 6 years to come to that conclusion.

Note You need to log in before you can comment on or make changes to this bug.