I have written this function below to return the values from the $_POST global that can be used in the PDO statement. I just want suggestions if this is a good way to do it. I know that the "implode" part might not be very flexible but i would like to know how this can be improved. Any help with the logic and improving the function is deeply appreciated. Thanks.
/**
* This function loops through the $_POST global and returns parameters that can be used in
* a PDO statement directly. Note : For this function to work properly the
* PDO::ATTR_EMULATE_PREPARES should be set to "false"
* like so "$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false)".
* @param Array $exclude This is an array of keys in $_POST that you want the function to ignore
* @return Array The function returns an array that can be used as parameters for the PDO statement
*/
function get_params($exclude = array()) {
$keys = array();
$values = array();
$placeholder_keys = array();
$params = array();
foreach ($_POST as $key => $value) {
if(!in_array($key, $exclude)) {
$keys[] = $key;
$placeholder_keys[] = ":" . $key;
if(is_array($value)){
$value = implode(",", $value);
}
$values[] = $value;
}
}
$comma_sep_keys = implode(",", $keys);
$comma_sep_placeholder_keys = implode(",", $placeholder_keys);
$params['keys'] = $keys;
$params['values'] = $values;
$params['placeholder_keys'] = $placeholder_keys;
$params['comma_sep_keys'] = $comma_sep_keys;
$params['comma_sep_placeholder_keys'] = $comma_sep_placeholder_keys;
return $params;
}
You're not sanitizing the keys at all. What if an array element is:
array(
"foo = ''; DROP TABLE users; --" => 'baz'
)
This leaves you wide open to SQL injection. You're placeholding the values, but in return you're blindly concatenating unsanitized keys into your queries.
You're also imploding array values into a single string; do you really want to insert them as the single value "foo,bar,baz"
when they were an array originally?
Expanding a bit to deceze in case it wasn't clear (and because that's the first thing I thought), your user could change the form to:
<input name = "foo = ''; DROP TABLE users; --" value = 'baz'>
Also, you are very vulnerable to XSS attacks. What if someone entered as a value this:
<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>
Then, everyone that enters in the page where that user's input can be read (most importantly, you), will load that xss.js
. This is very dangerous, and I recommend having a strict sanitizing rules. EDIT: Normally you should use htmlentities(), but only use them when outputting data, as can be learned in this question in SO. But, if you are accepting html, a good library for it is HTML Purifier.