Page 1 of 1
Function to avoid SQL injections & other threats
Posted: Wed Jan 24, 2007 2:57 pm
by BooGiE_MaN
Hi
Just joined and btw it spits out an error which doesn't make sense (I managed to get here after all):
Failed sending email :: PHP ::
DEBUG MODE
Line : 236
File : emailer.php
Anyway, want to know from you guys if the following function would make input safe, but allow me to develop relatively quickly:
Code: Select all
function makesafe(){
foreach ($_POST as $k => $v)
{
if (is_array($v))
{ $_POST[$k] = trim(mysql_real_escape_string(htmlentities($v, ENT_QUOTES))); }
else
{ $_POST[$k] = trim(mysql_real_escape_string(htmlentities($v, ENT_QUOTES))); }
/// question: would I be safe only going:
// $_POST[$k] = trim(htmlentities($v, ENT_QUOTES));
}
}
Usage would be, eg:
Code: Select all
if(isset($_POST['Submit'])){
makesafe();
$sql = "insert into `table` set `field` = '$_POST[value]' .............
Btw, I use htmlentities so that a rich-text editor can be used. I then use stripslashes(html_entity_decode()) to output the HTML. Any comments re security?
I read in one of the posts that $_GET items should be dealt with also; would you recommend (from the site-wide included file):
Code: Select all
foreach ($_GET as $k => $v)
{
if (is_array($v))
{ $_GET [$k] = trim(mysql_real_escape_string($v, ENT_QUOTES)); }
else
{ $_GET [$k] = trim(mysql_real_escape_string($v, ENT_QUOTES)); }
}
}
Your thoughts???
Posted: Wed Jan 24, 2007 3:12 pm
by Luke
input doesn't need to be
htmlentities()-ized. You do that on output.
mysql_real_escape_string() is for input.
Code: Select all
$name = (isset($_POST['name'])) ? mysql_real_escape_string($_POST['name']) : null;
// now insert into db
Then when you want to output:
Code: Select all
$name = htmlentities($mysql_result['name']);
echo $name;
Some reference:
http://pixelated-dreams.com/uploads/mis ... tSheet.pdf
viewtopic.php?t=29269
Posted: Wed Jan 24, 2007 3:31 pm
by Luke
Oh yea, one more...
http://phpsec.org/
Not the greatest resource yet, but I imagine it will be in the near future.
Posted: Wed Jan 24, 2007 4:02 pm
by John Cartwright
Your function won't work if you pass it an array. You need to recursively call your function to deal with arrays.
In my applications, I do something like this, but keep in mind this is for outputting content, not inputting into the database. All you'd need to do is replace htmlentities() with mysql_real_escape_string() though.. enjoy.
Code: Select all
public function escape($input, $charset = 'UTF-8')
{
if (is_array($input))
{
$return = array();
foreach($input as $key => $value)
{
if (is_array($value))
{
$return[$key] = $this->escape($value, $charset);
}
else
{
$return[$key] = htmlentities($value, ENT_QUOTES, $charset);
}
}
return $return;
}
else
{
return htmlentities($input, ENT_QUOTES, $charset);
}
}
Posted: Thu Jan 25, 2007 2:07 am
by BooGiE_MaN
Thanks guys
Out of curiosity, will using htmlentities() on its own (without mysql_real_escape_string()) prevent SQL injections?
Posted: Thu Jan 25, 2007 5:25 am
by matthijs
@jcart: isn't it possible with your code to overload php's memory by feeding a very big deep nested array as input, and with that crashing/slowing the script/server?
@Bookieman: no, html_entities is a function used to escape output to HTML. mysql_real_escape_string is a function to escape output to a mysql db.
Posted: Thu Jan 25, 2007 5:35 am
by BooGiE_MaN
htmlentities() converts ' " > etc to ' " > respectively.
Are there still characters that can't be converted and can cause SQL injections?
The thing is I don't want to have to go stripslashes() every time. With htmlentities I can just echo the data (if it is not actually HTML in which case you go html_entity_decode()).
Posted: Thu Jan 25, 2007 6:14 am
by matthijs
BooGiE_MaN wrote:htmlentities() converts ' " > etc to ' " > respectively.
Are there still characters that can't be converted and can cause SQL injections?
The thing is I don't want to have to go stripslashes() every time. With htmlentities I can just echo the data (if it is not actually HTML in which case you go html_entity_decode()).
You don't have to use strip_slashes. Mysql_real_escape_string only escapes special characters. There are no extra slashes added to the data.
It's really very simple. Output to mysql: always use Mysql_real_escape_string or prepared statements. Output HTML: always use htmlentities(). That really is best practice. leave one out and you take unnecessary risk.
Posted: Thu Jan 25, 2007 6:21 am
by BooGiE_MaN
If you echo data into a form element such as a textbox the slashes will appear and you'll need to stripslashes()
Posted: Thu Jan 25, 2007 6:46 am
by matthijs
That has nothing to do with mysql_real_escape_string. That is caused by the evil doings of
magic quotes.
To get rid of that, turn them off in php.ini or on script level with a function like this:
Code: Select all
if(get_magic_quotes_gpc()) {
$in = array(&$_GET, &$_POST, &$_COOKIE);
while (list($k,$v) = each($in)) {
foreach ($v as $key => $val) {
if (!is_array($val)) {
$in[$k][$key] = stripslashes($val); continue;
}
$in[] =& $in[$k][$key];
}
}
unset($in);
}
Posted: Thu Jan 25, 2007 7:16 am
by BooGiE_MaN
great thanks matt
This will work on a server with magic quotes on or off right?
Posted: Thu Jan 25, 2007 7:28 am
by matthijs
yes. It's a script from PHP architects guide to PHP security (Ilia Alshanetsky, great book). If you include this at the top of your script it will remove slashes in case magic quotes is on.