magic_quotes_gpc函数在php中的作用是判断解析用户提示的数据,如包括有:post、get、cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误。
在magic_quotes_gpc = On的情况下,如果输入的数据有
单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)等字符都会被加上反斜线。这些转义是必须的,如果这个选项为Off,那么我们就必须调用addslashes这个函数来为字符串增加转义。
正是因为这个选项必须为On,但是又让用户进行配置的矛盾,在PHP6中删除了这个选项,一切的编程都需要在 magic_quotes_gpc=Off下进行了。在这样的环境下如果不对用户的数据进行转义,后果不仅仅是程序错误而已了。同样的会引起数据库被注入攻击的危险。所以从现在开始大家都不要再依赖这个设置为On了。
我们可以通过以下代码来探测php环境中magic_quotes_gpc是否开启:
magic.php 源代码如下:
<?php
//当magic_quotes_gpc=On的时候,get_magic_quotes_gpc函数的返回值为1
//当magic_quotes_gpc=Off的时候,get_magic_quotes_gpc函数的返回值为0
if (get_magic_quotes_gpc())
{
echo 'magic_quotes_gpc 开启';
}
else
{
echo 'magic_quotes_gpc 未开启';
}
?>
比如我自己本地的PHP环境版本:
将magic.php 文件放在本地站点根目录之下测试,如图:
那么,说明:我的本地php环境,并没有开启magic_quotes_gpc,即,magic_quote_gpc=Off,或者magic_quote_gpc这个特性在我此时的php环境版本里面,已经被php社区废除了,那么,我在编写php代码的时候,就需要将magic_quotes_gpc设置为On,或者在php代码中使用addslashes函数对get,post,cookie等数组进行特殊字符转义,不然,此情此景,我编写的php代码就不安全了。
其实,我的本地magic_quotes_gpc默认设置如图:
接下来,介绍一下addslashes函数:
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串,预定义字符有以下这些:
他们分别是:
单引号(')
双引号(")
反斜杠(\)
NULL
例程如下(addslashes转义输入数据中的单引号):
<?php
echo '转义前:';
$str = "Who's Kevin David Mitnick?";
echo $str;
echo '<br />';
echo '转义后:';
echo addslashes($str);
?>
执行结果如下图:
问题:那么,我们怎么才能编写出安全的php代码呢?
答案:合理地使用好get_magic_guotes_gpc、magic_quotes_gpc、addslashes这3个函数。
比如,以下代码就是一些好的防MySQL注入的安全代码(php一般与MySQL配合使用),其中就涉及到了特殊字符的转义:
<?php
function SQLString($c, $t)
{
$c=(!get_magic_quotes_gpc())?addslashes($c):$c;
switch($t)
{
case 'text':
$c=($c!='')?"'".$c."'":'NULL';
break;
case 'search':
$c="'%%".$c."%%'";
break;
case 'int':
$c=($c!='')?intval($c):'0';
break;
}
return $c;
}
?>
<?php
function check_input($value)
{
//去除斜杠
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
//如果不是数字则加引号
if (!is_numeric($value))
{
$value = “‘” . mysql_real_escape_string($value) . “‘”;
}
return $value;
}
$con = mysql_connect(‘localhost’, ‘root’, ‘root’);
if (!$con)
{
die(‘Could not connect: ‘ . mysql_error());
}
//进行安全的SQL语句执行
$user = check_input($_POST['user']);
$pwd = check_input($_POST['pwd']);
$sql = “SELECT * FROM users WHERE user=$user AND password=$pwd”;
mysql_query($sql);
mysql_close($con);
?>
总结:
php较低版本(php version <= 5.3.0)会对所有的GET、POST和COOKIE 数据自动运行addslashes()。因为较低版本的php,magic_quotes_gpc默认开启,所以,此时您不应对已转义过的字符串使用 addslashes(),因为这样会导致双层转义。遇到这种情况时,可以使用函数get_magic_quotes_gpc()进行检测。