Question

I'm reading a book on php security, and on input validation chapter there's a small section that talks about only allowing expected input.

This is the code that they show:

<?php
$expected = array( 'carModel', 'year', 'bodyStyle' );
foreach( $expected AS $key ) {
if ( !empty( $_POST[ $key ] ) ) {
${$key} = $_POST[ $key ];
}
else {
${$key} = NULL;
}
}
?>

I'm kind of confused, there's a small paragraph that explains what the code does. For what I get it assigns a value from the array as a key to $_POST. It also says that the array should be done programatically copied out of the GPC array.

What I don't understand is in what cases should I use this? And what is the GPC array?

Was it helpful?

Solution 2

The code creates variables from data in the $_POST array. The names of the variables are taken from the keys of the $_POST array. PHP calls this (i.e. naming variables dynamically) variable variables.

This is usually a bad idea, because you do not control, which keys are present in the $_POST array, and thus, which variables are created. The user of your website controls this. A malicious user might name the POST variables in such a way that they overwrite variables that you intended for different purposes.

The book suggests to allow keys in the $_POST array to overwrite variables in a controlled manner. That's what $expected = array('carModel', 'year', 'bodyStyle') is for. This and the following code only creates the variables $carModel, $year and $bodyStyle. If, for example, a user posts current_user_has_admin_rights=1 to you application, a variable $current_user_has_admin_rights with a value of 1 will not be created.

My suggestion is to to stay away from variable variables alltogether and instead access the POST values through the $_POST array only. This makes it clear where the value comes from, an thus makes it easier to spot if such a value is handled in an unsecure manner.

OTHER TIPS

GPC = Get Post Cookie, it's referring to variables coming from the user/browser. So instead of using $_GET, $_POST, $_COOKIE you should be cleaning and validating that data into a variable(s) that you can trust and know is clean.

As for the suggestion, what they are doing is limiting what your code has access to. In the above code example, you would probably have a form on the page with elements named carMOdel, year, and bodyStyle. What the code here is doing is restricting your code to ONLY interact with those 3 elements.

This prevents someone from passing extra parameters to your page in an attempt to inject code or some sort of SQL injection attack or any other number of things. In a simple example like this it might not make sense. But there are cases where people are taking form/api requests and running loops over everything in one of GPC arrays and doing stuff with anything in there. I would suggest not doing that to begin with.

This is just 1 of MANY things to protect your server/database. When developing webapps you should take the stance of trusting NOTHING that comes from the user side.

As far as security goes, OWASP is a great source for learning. here is a little cheat sheet that is in the works for php.

It also says that the array should be done programatically copied out of the GPC array.

This could mean that you shouldn't necessarily write:

$expected = array('carModel', 'year', 'bodyStyle');

Rather write something like:

$expected = getExpectedInput('carForm');

Where the function getExpectInput would query the database for the input that should be in the form 'carForm'. Or perhaps it could be in a file and this function would fetch that content. They basically mean, it's not a good idea to hard-code the variables in the form. Rather write them somewhere so they are easy to change. If you ever made changes to the form and added a variable or changed a variable name, you don't have to change this particular code. This means that this function is usable on different forms. The idea is to write function that that can be re-used. Not those that are dedicated to one thing. OOP.

The getExpectedInput function would probably return an array. You can name this whatever you like or use any method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top