One of the reasons KnowledgeTree is written in PHP is so that it will be easier for companies to use - PHP is well-understood by admins, and PHP hosting accounts are common. But PHP brings all sorts of problems with it too, which I'm learning to deal with.

One big problem in writing PHP applications that will run on all these hosts is the variety of PHP configuration options on various hosting environments and defaults on different PHP distributions.

Especially in hosting environments, often you have no control over the configuration options your PHP application will run under, so as a developer you need to try work with all combinations possible.

One of the biggest problems is magic_quotes_gpc, a configuration option that controls the input your application will receive. It attempts to prevent developers from doing something stupid by messing with data in a way that breaks things if the developer writes code properly.

It's a trade-off. To accurately ensure the integrity of the data, you can't have this happen to your data behind your back. But if you let this happen, a whack of SQL injection attacks are stopped.

Whichever you choose, you have to get data in either case to the same point form. You can't just change the magic_quotes_gpc setting in your code - the data you're dealing with has already been populated before your code starts. I recommend stripping slashes if magic_quotes_gpc() returns true.

Here's what I use in KnowledgeTree, based on various code I took a look at:

    // {{{ cleanMagicQuotesItem()
    function cleanMagicQuotesItem (&$var) {
        if (is_array($var)) {
            foreach ($var as $key => $val) {
                KTInit::cleanMagicQuotesItem($var[$key]);
            }
        } else {
            // XXX: Make it look pretty
            $var = stripslashes($var);
        }
    }
    // }}}

    // {{{ cleanMagicQuotes()
    function cleanMagicQuotes () {
        if (get_magic_quotes_gpc()) {
            KTInit::cleanMagicQuotesItem($_GET);
            KTInit::cleanMagicQuotesItem($_POST);
            KTInit::cleanMagicQuotesItem($_REQUEST);
            KTInit::cleanMagicQuotesItem($_COOKIE);
        }
    }
    // }}}

In the application initialisation (KTInit namespace), this code ensures the data is in its natural state no matter the setting.

Another setting, which of late is almost always disabled, is register_globals. However, when I arrived, KnowledgeTree relied on it. Using register_globals has no real upside beyond a few saved keystrokes, and introduces many issues for beginner programmers around security.

The choice here was obvious. Putting stuff from the various request variables into the global namespace manually is fraught with issues. So, the arduous task of making KnowledgeTree use request variables rather than expecting register_globals began. To ensure maximum correctness and repeatable testing, I wanted to make sure that even if register_globals was set, the added variables were not available.

TikiWiki had a succinct and accurate way of doing this, which I borrowed:

    // {{{ cleanGlobals()
    function cleanGlobals () {
        /*
         * Borrowed from TikiWiki
         *
         * Copyright (c) 2002-2004, Luis Argerich, Garland Foster,
         * Eduardo Polidor, et. al.
         */
        if (ini_get('register_globals')) {
            foreach (array($_ENV, $_GET, $_POST, $_COOKIE, $_SERVER) as $superglob) {
                foreach ($superglob as $key => $val) {
                    if (isset($GLOBALS[$key]) && $GLOBALS[$key] == $val) {
                        unset($GLOBALS[$key]);
                    }
                }
            }
        }
    }
    // }}}

These two changes are among the many I made to bring about the KnowledgeTree 2.0 release. The major release bump had more to do with wanting to distinguish the increased robustness and suitability to more environments than actual features.

Of course, if all your users are the sort who can organise .htaccess files to work for your application's directory, you can just get away with this in a .htaccess file in your application's web root:

php_flag magic_quotes_gpc OFF
php_flag register_globals OFF

One thing I haven't even really started looking at is supporting PHP's safe_mode, which prevents the PHP application from doing many malicious things. This seems to be mostly common in smaller hosting packages, although one company running their own server requested it too.

(Yes, this is similar to my post on KnowledgeTree modernisation, but this is just the introduction for the upcoming parts, and also a better explanation of the issues (hopefully).

1 Responses

  1. R.I.PienaarMay 12, 2005 at 03:15 PM.

    I use http://cyberai.com/inputfilter/ to sanitise my user input

Have your say

The text area above accepts Post Markup, a BBCode work-alike.

[b]foo[/b]: foo
[i]foo[/i]: foo
[link]http://nxsy.org/[/link]: http://nxsy.org/ [nxsy.org]
[link http://nxsy.org/]Neil[/link]: Neil [nxsy.org]
        

You can also use:

[code python]
import foo
[/code]