PHP Security
Per Wigren writes: "This is a REALLY good article on PHP security! It's scary how easy it is to leave security holes in code that looks secure at the first glance. Every PHP coder should read this! Seconds after reading this I stopped my webservers for an audit and I found and closed several potential holes in my code..."
Touching this as REALLY good is exorbitant. It tells errors common to other web languages too; not only related to PHP.
And seriously, if you are using PHP and haven't fullfilled more than 80% from this paper anyway you should go home to Big Mum and read docs before coding.
I prefer this snippet to get form values into globals:
foreach ($HTTP_POST_VARS as $k=>$v)
$$k=$v;
This way you still get your globals but you get only them from the POST. No matter what you do in your code you can't hide from a spoofed POST but at least you can avoid spoofed GET vars.
--------
Yeah, I'm a Mac programmer. You got a problem with that?
-- thinkyhead software and media
In php.ini:
:^)=
error_reporting = E_ALL
register_globals = Off
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
Make sure that your code works with the above configuration directives, and many of the security problems mentioned in the above article go away. Follow the author's recommendation about not allowing URL access in 'file' functions, and you're just about as safe as possible.
The reasion you want to turn magic quotes off is because it's impossible to tell in PHP whether a given string has been quoted already or not (ie: it's magic), especially when you're redisplaying posted information in an HTML form in order to allow the user to correct their mistakes.
Since typing out $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_SESSION_VARS, $HTTP_COOKIE_VARS is a reeeeal mouthful to type over and over again, I took the liberty of making a function called 'gpc()' which will get a requested variable following the rules of Get/Post/Cookie ordering set in the ini file. Your globals namespace stays 100% unpolluted unless you specifically request that your variable comes from an insecure (get/post/cookie) request.
Just remember: htmlspecialchars, escapeshellcmd, and addslashes are your friends. Use them in the right places and trust no one.
--Robert
I looked at it. Sure it was convenient and all that. But it's _almost_ as if it was designed to be insecure.
d efault,$min,$max).
:(.
That global variables behaviour was a big decider for me to not use PHP. Whereas for a lot of PHP programmers the global variable behaviour seems to be a core functionality they use PHP for!
It seems when you turn those insecure features off you lose much of the essence of PHP. It'll just be like writing in some other language, Perl for instance. Instead of PHP putting variables in your namespace on a platter, you have to do things much like Perl's $var=param('paramname');. I personally run most CGI parameters through a filter. e.g. ($var,$errcode)=myparam('paramname','paramtype',$
I'm not saying PHP can't be secure, but the point is the PHP style seems to go against the grain of security. And if you don't use the PHP style, there are far fewer reasons to use PHP.
For a real life example of what typically happens, see PHP Nuke. Featurewise it's great and all that. But looking at it from a security perspective
A server-side web language can be almost as convenient as PHP without sacrificing security. For example, with BRL you simply declare your input variables, e.g.
Then those four variables, and only those four variables, take their values from form inputs. This is less convenient than PHP's default behavior, but more convenient than doing foo=$HTTP_POST_VARS['foo']; over and over. (I'm working on a BRL page today that takes 24 inputs!)
Hopefully PHP will add a similar feature in a future release.
A cracker is not going to have any more difficulty making fake POST variables than s/he would with GET variables. You have essentially the same lack of security as normal PHP.
See the PHP Manual's section on security as a good place to start.