-
These are a couple of pointers I distilled from two articles(1)(2) on the topic of securing PHP. Although I'm not an expert, I added bits and pieces as well.
Basically, two general rules have to be kept in mind:
[list=a][*]What rights are assigned to the scripts running on my system, and[*]How much information about my system, php-configuration and scripts is visible to the outside world?[/list=a]
Configuring options for rule ‘a’ (these settings can be modified/applied in your configuration file, usually php.ini):
- safe_mode – turning this on will prevent a user from reading files not owned by the user.
- open_basedir – limits the (number of) directories to which your scripts have acces.
- disable_functions – use this to disable php-functions of your choice (ie: if you don’t want your users to be able to make use of php function foo(), put that in here).
- register_globals – when this is turned on, others are able to initiate a value of a variable that the developer forgot to initiate. Disable this setting to counter this behavior.
Configuring options for rule ‘b’ (visibility of information):
- expose_php – disable this to disallow PHP to generate version-information in http headers.
- display_errors – if enabled, php will display errors in generated pages. This is useful during development, but you should disable this once your scripts go live.
- error_log – instead of having your errors being reported in the generated output, save them in a file that you specify in this option.
Apart from this, a developer has to keep an eye on how PHP handles EGPCS (Environment, GET, POST, Cookie, Server) variables. Apart from the already mentioned SQL-injection problems (allowing unchecked GPC-variables in queries), there’s a risk that these variables will be instantiated from the outside. Check the mentioned register_globals configuration setting for more information.
Last couple of hints:
- More information on can be found on http://www.php.net - this site provides excellent documentation.
- In scripts, you can check whether or not register_globals is set by calling the registerGlobals() function.
- If you’re using MySQL, the new MySQLi (‘MySQL improved’) functions should provide better security (anti-SQL-injection wise) than the old MySQL functions. MySQLi is available as of PHP 5.0.0, as far as I know.
- To counter sql-injection, there are numerous functions that escape strings – there’s also a configuration setting that forces PHP to escape all GPC (GET, POST, Cookie) variables. Check the Magic_Quotes_GPC setting and function. Make sure though that you don’t double-escape variables – that’ll get messy quick.
References:
1: Security.nl, PHP security, article 1 (Dutch)
2: Security.nl, PHP security, article 2 (Dutch)