foreach loop not working - php

I'm trying to use a foreach loop to search for word in $_POST, but it doesn't work? Help is preciated.
$unsafeWords = array('content-typ','bcc','cc');
foreach ($_POST as $key => $input) {
foreach ($unsafeWords as $value) {
$_POST = str_ireplace($value, "", $input) ;
}
}

Don't overwrite the $_POST array with a string
$unsafeWords = array('content-typ','bcc','cc');
foreach ($_POST as $key => $input) {
foreach ($unsafeWords as $value) {
$_POST[$key] = str_ireplace($value, "", $input) ;
}
}
though I dislike overwriting the original $_POST array and would prefer to build a new array of cleaned values
Note that you don't need to loop the $unsafeWords array, but can pass an it as an array directly to str_ireplace()
EDIT
Example of using the $unsafeWords array as an argument for str_ireplace() rather than looping through it with foreach() and calling str_ireplace() for each entry.
$unsafeWords = array('content-type','bcc','cc');
foreach ($_POST as $key => $input) {
$_POST[$key] = str_ireplace($unsafeWords, "", $input) ;
}
and you're not replacing with a space, you're replacing with an empty string (effectively removing the unsafe strings from your $_POST vars)
EDIT 2
I guess it's OK to put this inside the
foreach loop as well?
Not quite... if you're just adding it as an extra line within the loop, you'll overwrite your previous substitutions.
Do it as:
$unsafeWords = array('content-type','bcc','cc');
foreach ($_POST as $key => $input) {
$_POST[$key] = str_ireplace($unsafeWords, "", filter_var($input, FILTER_SANITIZE_STRIPPED)) ;
}

You are trying to overwrite $_POST (which is an array) with string values. The correct way is this:
foreach ($_POST as &$input) {
$input = str_ireplace($unsafeWords, array(), $input) ;
}
The above code also takes advantage of a couple other features (foreach with a reference as loop variable, str_ireplace accepting arrays) to be much shorter.

Not completely clear what you're asking but this:
$_POST = str_ireplace($value, "", $input) ;
definitely won't do what you expect. You probably want:
$_POST[$key] = str_ireplace($value, "", $input) ;

Try this instead (missing $key at the assignment)
$unsafeWords = array('content-typ','bcc','cc');
foreach ($_POST as $key => $input) {
foreach ($unsafeWords as $value) {
$_POST[$key] = str_ireplace($value, "", $input) ;
}
}

Aside form that foreach problem, it seems very insufficient validation in terms of mail injection protection.
For the email field I'd use some regexp-based or filter_var() solution.
For the name and subject fields I'd suggest to encode it according to RFC rules.
So, I believe that safe code could be (in case of utf-8 encoded email):
if ($email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
$subject = "=?UTF-8?B?".base64_encode($_POST['subject'])."?=";
$from = "From: =?UTF-8?B?".base64_encode($_POST['name'])."?= <$email>\r\n";
$message = str_replace("\n.", "\n .", $_POST['text']);
mail('me#example.com',$subject,$message,$from);
}

If you want to remove indexes from the $_POST array that are specified in the $unsafeWords, then you went on with the wrong approach. Use unset() function to remove the index you don't want or simply set it to
foreach($_POST as $key => $input)
{
if(in_array($input, $unsafeWords)
{
$_POST[$key] = null; // or $_POST[$key] = '' or unset($_POST[$key]
}
}

Related

PHP: Side effects of trimming all values in superglobals ($_GET, $_POST, $_COOKIE, $_REQUEST)

I know that many people believe it is wrong to edit Superglobals in PHP. But I found myself to always trim user input in every controller of my webapp. To solve the problem once and for all I now just trim all values of these Superglobals like that:
# trim ALL inputs
foreach ($_REQUEST as $key => $value) {
$_REQUEST[$key] = trim($value);
}
foreach ($_COOKIE as $key => $value) {
$_COOKIE[$key] = trim($value);
}
foreach ($_GET as $key => $value) {
$_GET[$key] = trim($value);
}
foreach ($_POST as $key => $value) {
$_POST[$key] = trim($value);
}
Some users might want to define a password that starts or ends with a whitespace. Apart from that I cannot think of any usecase where trimming might do any harm.
Has anybody else tried to trim these Superglobals and ran into strange side effects that I should be aware of?

PHP function on array only returning first value

I created a function to iterate through the $_GET array and, after verifying the data, create a constant for each element. However, it only returns the first constant.
function sanitize($key, $value){
$safe_types = array(
"month",
"year",
"course",
"pagetype",
"studentid"
);
if (in_array($key, $safe_types)) {
$key = strtoupper($key);
if (is_numeric($value) || preg_match("#^[a-z_]+#", $value)){
define ($key, $value);
}
}
}
foreach ($_GET as $key => $value) {
sanitize($key, $value);
}
I also tried array_walk with no better result.
Thank you all for taking a look and telling me it worked for you.
The issue was not the $_GET array provided but how I was testing the results. I had the following:
echo
"<br/>month: ".MONTH;
"<br/>course: ".COURSE;
"<br/>pagetype: ".PAGETYPE;
"<br/>studentid: ".STUDENTID;
. . .but of course should have had periods instead of semicolons.

PHP Notice: Array to string conversion Error

Been experiencing this error for a little while and can't find any conclusive answers on fixing it. I have tried removing quotes from $key in line 59 but to no avail.
if (!get_magic_quotes_gpc()) {
if (isset($_POST)) {
foreach ($_POST as $key => $value) {
$_POST['$key'] = trim(addslashes($value));
}
}
if (isset($_GET)) {
foreach ($_GET as $key => $value) {
$_GET[$key] = trim(addslashes($value));
}
}
}
LINE 59
$_POST['$key'] = trim(addslashes($value));
Error On Screen
Notice: Array to string conversion in
C:\Inetpub\vhosts\domain.com\httpdocs\library\config.php on
line 59
Check if it is array before you assign it
$_POST[$key] = !is_array($value) ? trim(addslashes($value)) : '';
// ^ Remove the quotes here // ^ Do something
// Instead of
// Using empty
According to PHP.net the function addslashes() takes a String type as parameter. Check what type $value is. If it is an array itself then addslashes() may be throwing the error.
PS:
You should use $_POST[$key] rather than $_POST['$key'] if you want to use the value of $key as the index of the $_POST array.
I think you should use this code $_POST[$key] = $value; instead of using this $_POST['$key'] = trim(addslashes($value));
or make a check if the value is in array or not
Do this:
foreach ($_POST as &$value) {
$value = is_array($value) ?
array_map(function($x) { return trim(addslashes($x)); } :
trim(addslashes($value));
}
However, this could still fail if any of your parameters are multi-dimensional arrays. As mentioned in the comments, the right solution is to use prepared queries with parameters, rather than interpolating strings into SQL.

remove all but last comma

i have the following code:
while (list($key, $value) = each($arr)) {
$implode_keys_values = #"$key=$value,";
echo"$implode_keys_values";
}
which ends up echoing out xxxx=xxxx,xxxx=xxxx,xxxx=xxxx,xxxx=xxxx,
depending on how many keys/values there are.
how do I take this dynamically changing string and remove the very last comma on it?
keep in mind:
$implode_keys_values = substr($implode_keys_values,0,-1);
will not work, it will take out all the commas.
rtrim($implode_keys_values, ",") would cut trailing commas.
You can learn more about rtrim here at the PHP docs
$implode_keys_values = "";
while (list($key, $value) = each($arr)) {
$implode_keys_values .= #"$key=$value,";
}
echo rtrim($implode_keys_values, ",");
PHP has a function built in for that if the data in the array is not too complex (works for the xxxxxx values you have, can break with others):
echo http_build_query($arr, '', ',');
See http_build_query().
Another alternative is using iterators and checking if the current iteration is the last one. The CachingIterator::hasNext() method is helpful for that:
$it = new CachingIterator(new ArrayIterator($arr));
foreach($it as $key => $value) {
echo $key, '=', $value, $it->hasNext() ? ',' : '';
}
This variant does work with any data.
In your case, this would be a better way to implement implode():
$data = array();
while (list($key, $value) = each($arr)) {
$data[] = "$key=$value";
}
echo implode(",",$data);

Why am I getting this Array to String Conversion Notice

I am using an eCard program here to send invitations for an event and get the following notice:
Notice: Array to string conversion in
/nfs/c07/h01/mnt/108712/domains/christmasnativity.org/html/ecard/include/common.inc.php
on line 32
Here is the code from lines 29 to 33:
/* Clean up request: Remove magic quotes, if the setting is enabled. */
if (get_magic_quotes_gpc()) {
foreach($_REQUEST as $name => $value)
$_REQUEST[$name] = stripslashes($value);
}
Any clues what may be causing this error notice?
Thanks.
One of the values in $_REQUEST is an array. This can happen if a variable uses a name such as foo[].
You can avoid running stripslashes on arrays like this
if (get_magic_quotes_gpc()) {
foreach($_REQUEST as $name => $value)
if(!is_array($value)){
$_REQUEST[$name] = stripslashes($value);
}
}
but then the values inside an array $value won't get stripped.
A more complete solution would be something like this:
if (get_magic_quotes_gpc())
{
strip_slashes_recursive($_REQUEST);
}
function strip_slashes_recursive(&$array)
{
foreach ($array as $key => $value)
{
if (is_array ($value))
{
strip_slashes_recursive ($array[$key]);
}
else
{
$array[$key] = stripslashes($value);
}
}
}
Like Ignacio Vazquez-Abrams says, one of the $value's is an array. You can use the following to see what is an array (assuming you are/can output the results to somewhere you can see them):
$_REQUEST[$name] = stripslashes($value);
var_dump($value);

Categories