Mailing List Archive

PHP code inclusion through include files - a tentative solution
Hello all,

Thanks for the comments. I have modified the previous hack to do what
we've discussed earlier today:

If you include the following snippet in setup.php:

function IncludePHP($Content)
{
global $wgOut;
$wgOut->enableClientCache(false);
ob_start();

//match for only text and numbers, followed by a period followed by 'php'
if(ereg("^([a-z]|[0-9])*.php$",$Content)==true){
$Content = "include('$Content');";
}
else{
$Content = "echo \" <strong>invalid include file specified <strong>\";";
}
eval($Content);
$Result = ob_get_contents();
ob_end_clean();
return($Result);
}

$wgParser->setHook('includephp','IncludePHP');

(to make it work, you put the php code in "filename.php", upload it to
your wiki directory then use the syntax
<includephp>filename.php</includephp>

In my wiki, this works beautifully - only *.php files in my wiki
directory are executed. Everything else is rejected. It's a simple
matter of tweaking the regex to allow subfolders too.

Comments about the effectiveness of this are appreciated ... =)


Taneem Talukdar


On Tue, 9 Nov 2004 23:07:33 +0000, Rowan Collins
<rowan.collins@gmail.com> wrote:
> On Tue, 9 Nov 2004 08:21:25 -0700, Taneem A T <thezeropoint@gmail.com> wrote:
> > So I was thinking, could we modify the hack so that you couldn't put
> > in PHP directly into the Wiki but you could include an external PHP
> > file whose code would be executed?
>
> Perhaps this would be a good reason to implement the ability to
> include [some?] Special: pages as templates, as requested at
> http://bugzilla.wikipedia.org/show_bug.cgi?id=813
>
> That way, the PHP code could only be written by someone with access to
> the wiki's source directory, and there would be no need to validate
> filenames, as none would ever be directly given (they would be
> produced by Title.php, presumably).
>
> I don't know how easy this would be to implement cleanly, though,
> given the mixed wiki-text/raw html output of current Special pages.
> Maybe SpecialPage.php could have an "executeAsTemplate()" method,
> which returned wikitext to be included if the page was requested as an
> inclusion. That way, it could return "" by default, and potentially
> format things differently than accessing the page normally; and a site
> administrator could create Special: pages to do custom bits of php,
> even giving them parameters (either using the sub-page style, like
> [[Special:Whatlinkshere/foo]], or by having template parameters passed
> to exeuteAsTemplate() - in an associative array or somesuch. Hm, I
> think I'll shove this suggestion on the bug report...
>
> --
> Rowan Collins BSc
> [IMSoP]
>
Re: PHP code inclusion through include files - a tentative solution [ In reply to ]
On Nov 9, 2004, at 11:25 PM, Taneem A T wrote:
> If you include the following snippet in setup.php:

You generally shouldn't modify Setup.php; extensions should be loaded
in LocalSettings.php.

> function IncludePHP($Content)
> {
> global $wgOut;
> $wgOut->enableClientCache(false);
> ob_start();
>
> //match for only text and numbers, followed by a period followed by
> 'php'
> if(ereg("^([a-z]|[0-9])*.php$",$Content)==true){

Don't forget that "." is a special symbol in regular expressions, which
matches any character except a newline. You need to use "\." to be sure
it only matches a period.

> $Content = "include('$Content');";

Depending on PHP configuration this can produce an error message if the
file is not present. (Such error messages can include the full path to
the files on your server, which some consider dangerous information
which crackers might be able to use to aid an exploit of your system
through other means. You should set PHP not to display error messages
if this bothers you; you can still log them.)

It also might produce very undesirable results given a request for
something like "index.php" or "redirect.php" which is in the current
directory or include path but is not supposed to be (re-)executed in
the middle of the wiki.

You might want to prepend a (set by you) path to where the acceptable
files are kept, and do a file_exists() check before running the
include().

> eval($Content);

This eval() seems unnecessary; the statements can be executed directly.

-- brion vibber (brion @ pobox.com)
Re: PHP code inclusion through include files - a tentative solution [ In reply to ]
> > $Content = "include('$Content');";
>
> Depending on PHP configuration this can produce an error message if the
> file is not present. (Such error messages can include the full path to
> the files on your server, which some consider dangerous information..."

I thought of this and tested it - the server I'm on has debug messages
turned off - all I get is a blank. However for my own purposes I could
test if include() returns a true or false value (provided the included
file returns nothing) and give a custom error message?

>
> It also might produce very undesirable results given a request for
> something like "index.php" or "redirect.php" which is in the current
> directory or include path but is not supposed to be (re-)executed in
> the middle of the wiki.
>

Yes I should have remembered this - a simple solution I can think of
is to specify a subfolder dedicated just to my own php files.

Apart from that, thanks for all the points - as you can probably tell,
I'm just learning all this stuff, so your comments are really
appreciated =)

Regards,
Taneem Talukdar
Re: PHP code inclusion through include files - a tentative solution [ In reply to ]
Should I assume then that only trusted users (eg, sysops) can upload files?

The main security issue, I think, is not what is included, but what is
in the file. To me, this seems obvious. (Think about how much info can
be gleamed from the INI settings, or the $GLOBALS array).

You are certainly on the right track with this, I think.

If you want to anylize where it is pointing, I find explode() pretty
helpful (though you will probably have to replace "\\" with "/").
Don't forget that PHP will look in all the include directories, not
just the current one.

On Wed, 10 Nov 2004 00:25:03 -0700, Taneem A T <thezeropoint@gmail.com> wrote:
> Hello all,
>
> Thanks for the comments. I have modified the previous hack to do what
> we've discussed earlier today:
>
> If you include the following snippet in setup.php:
>
> function IncludePHP($Content)
> {
> global $wgOut;
> $wgOut->enableClientCache(false);
> ob_start();
>
> //match for only text and numbers, followed by a period followed by 'php'
> if(ereg("^([a-z]|[0-9])*.php$",$Content)==true){
> $Content = "include('$Content');";
> }
> else{
> $Content = "echo \" <strong>invalid include file specified <strong>\";";
> }
> eval($Content);
> $Result = ob_get_contents();
> ob_end_clean();
> return($Result);
> }
>
> $wgParser->setHook('includephp','IncludePHP');
>
> (to make it work, you put the php code in "filename.php", upload it to
> your wiki directory then use the syntax
> <includephp>filename.php</includephp>
>
> In my wiki, this works beautifully - only *.php files in my wiki
> directory are executed. Everything else is rejected. It's a simple
> matter of tweaking the regex to allow subfolders too.
>
> Comments about the effectiveness of this are appreciated ... =)
>
> Taneem Talukdar
>


--
-------------------------------------------------------------------
http://endeavour.zapto.org/astro73/
Thank you to JosephM for inviting me to Gmail!
Re: PHP code inclusion through include files - a tentative solution [ In reply to ]
> Should I assume then that only trusted users (eg, sysops) can upload files?
>
> The main security issue, I think, is not what is included, but what is
> in the file. To me, this seems obvious. (Think about how much info can
> be gleamed from the INI settings, or the $GLOBALS array).

This is true - the wiki file upload settings are set to the defaults -
can't upload anything except pictures and such. Only people with
access to the server through ftp can actually upload any php files. So
it's just the admins.

> If you want to anylize where it is pointing, I find explode() pretty
> helpful (though you will probably have to replace "\\" with "/").
> Don't forget that PHP will look in all the include directories, not
> just the current one.

Thank you, I will look into using this =)

Taneem Talukdar

>
> On Wed, 10 Nov 2004 00:25:03 -0700, Taneem A T <thezeropoint@gmail.com> wrote:
> > Hello all,
> >
> > Thanks for the comments. I have modified the previous hack to do what
> > we've discussed earlier today:
> >
> > If you include the following snippet in setup.php:
> >
> > function IncludePHP($Content)
> > {
> > global $wgOut;
> > $wgOut->enableClientCache(false);
> > ob_start();
> >
> > //match for only text and numbers, followed by a period followed by 'php'
> > if(ereg("^([a-z]|[0-9])*.php$",$Content)==true){
> > $Content = "include('$Content');";
> > }
> > else{
> > $Content = "echo \" <strong>invalid include file specified <strong>\";";
> > }
> > eval($Content);
> > $Result = ob_get_contents();
> > ob_end_clean();
> > return($Result);
> > }
> >
> > $wgParser->setHook('includephp','IncludePHP');
> >
> > (to make it work, you put the php code in "filename.php", upload it to
> > your wiki directory then use the syntax
> > <includephp>filename.php</includephp>
> >
> > In my wiki, this works beautifully - only *.php files in my wiki
> > directory are executed. Everything else is rejected. It's a simple
> > matter of tweaking the regex to allow subfolders too.
> >
> > Comments about the effectiveness of this are appreciated ... =)
> >
> > Taneem Talukdar
> >
>
>
> --
> -------------------------------------------------------------------
> http://endeavour.zapto.org/astro73/
> Thank you to JosephM for inviting me to Gmail!
>