Posted by simonw on Mon 4 Feb 2013 at 15:55
This article describes the setting up of PECL Taint module for PHP5 in Debian Squeeze.
You will want to install the PECL taint module if you develop PHP applications, or if you test and deploy bespoke PHP code written for you by third parties.
The installation of Taint is easy, and it may detect security errors in your PHP code.
The idea of Taint is analogous to the Perl taint option.
When PHP code is executed input from untrusted sources is flagged as "tainted" by the Taint module, and unless the code calls a routine known to remove this flag, use of the variable is considered suspect and raises a warning (or error if so configured).
Like all automated security checks PHP Taint is not fool proof, on the other hand it will spot easily detectable security issues, and my experience of such errors is it is always the little bit you added-on in a hurry, or the extra PHP file you included which you forgot could be accessed directly, that breaks your site's security.
Typically you will want to deploy the Taint module on development or staging servers, and run coverage type tests so that all your PHP code is executed with Taint enabled, and check if any errors are produced. It is advised against running the Taint module in production.
Taint was written by Wietse Venema (of Postfix and TCPwrapper etc) and is maintained by Xinchen Hui.
Backup your server if you haven't already.
First you want to install package "php-pear" to install PECL modules.
# apt-get install php-pear
(the above command will install Apache and PHP5 if you don't have them already).
# pecl install taint
That wasn't too hard. In theory when it is out of date you can type "pecl install taint" again, although I note currently it doesn't install under Debian Wheezy as that has PHP 5.4.4 (as far as the install script is concerned) and taint currently only builds against PHP versions 5.2>= and =<5.4, note the version of PHP in Wheezy has a different default character set to Squeeze, so upgrades ARE unpleasant for PHP coders (as they were for upgrading to Squeeze with the renaming of the HTTP server variables in PHP - Perl generally doesn't do this to its users with every upgrade).
Create a file named "/etc/php5/apache2/conf.d/taint.ini" with these contents:
extension=taint.so taint.enable=On taint.error_level=E_WARNING
Make sure that file has appropriate permissions (root root r--r--r-- are fine) and restart Apache:
# service apache2 restart
("apache2ctl graceful" works too)
Create a file "test.php" with these contents, which is a script that allows cross site scripting (you might want to skip this if this isn't a secured development box).
<?php $test = $_GET['test']; echo $test; ?>
If you do not understand why this code is suspect, Taint really is for you, but see the Wikipedia page on Cross Site Scripting. Although failure to validate inputs can cause other types of security issue in web applications, such as SQL injection which is potentially a lot nastier.
Visit the URL corresponding to the "test.php" file above, passing "test=hello_world" as a parameter._
You should see a message like:
Warning: main(): Attempt to echo a string that might be tainted in /...path.to.test.file.../test.php on line 3
The error will either be in the appropriate Apache error log, or displayed in the resulting web page. If you can't find it in either location, check the settings in "/etc/php5/apache2/php.ini" for "display_errors" "log_errors" and "error_reporting" fix as appropriate, restart Apache and check again. If that fails create a file calling the "phpinfo();" function to check if the module is loaded correctly.
Remove the "test.php" file once you have established the Taint module is working, or figure out how to secure it!
Your installation is complete, you can run coverage tests on your PHP code now.
Always log errors to the Apache error log (as well as the screen if you like), since it is easy to miss errors displayed on the screen. Alternatively you can set the error_level of Taint higher and force the PHP to stop when an error is encountered in testing. Either method is safer than only display errors in a web page.
The settings can be set by the "ini_set" function on a per PHP file basis.
The Taint module introduces 3 functions, "taint", "untaint", and "is_tainted" whose use is hopefully obvious at this point, but can be used to make up for any failings of the taint module, or let you write test harness code.
Please add comments for errors and omissions.