当使用thinkphp框架接受表达内容。

如果使用I函数获取表单数据,如I("data");这个数据是默认被过滤的。

默认的过滤方法

'DEFAULT_FILTER'        =>  'htmlspecialchars', // 默认参数过滤方法 用于I函数...

如果对输入的参数进行正则匹配,当遇到特殊字符时会出问题。

htmlspecialchars的反函数为htmlspecialchars_decode()。使用该函数可以把转义的参数再转回来。

但这并没有解决全部问题,因为不同版本的thinkphp的I函数是不一样的,而且DEFAULT_FILTER还可以设置别的值。

所以当我们确实需要获取原始数据而非转义数据时,还是使用最原始的 $_POST("PARAM");最靠谱。


但是这事还是没完。因为php里还有addslashes()函数他会过滤提交给php的参数。也就是用原始的$_POST依然要面对过滤的问题。

我可以通过get_magic_quotes_gpc()来判断是否开启了该过滤,并用stripslashes()反过滤。

不幸的是,不同版本里的php对该函数的支持依然不同,php6里该函数被取消了。


综上,你不得不再每个项目里去测试框架和php参数的过滤,以使项目按照您的意愿执行。

另外如果您的php框架使用的是gbk的编码的话,那么还会出现字符集转换的问题,但这并不代表使用utf-8字符集时不会有问题。

总之对于输入参数的过滤转义,和字符集的转化都是非常麻烦而且特例特测的事情。


测试技巧。

不要仅直接用输入和输出的方式来测试,因为这个过程可能经历了多个过滤。

使用在php文件中定义变量然后输出,测试输出没有问题,再测试$_POST,再测试I函数。

如果要确保输入的数据安全还是自己用正则表达是来过滤一般,这是最靠谱的啦。

其次I(函数)的安全性还是有的,一般情况尽量使用I(函数)

特别情况,尽量使用$_POST来处理,一方面是效率更高而且代码中区别对待可读性好,还有就是不必关心DEFAULT_FILTER参数的设置。

在php5中去反addslashes()的函数

 

  1. //去掉在引号前面自动加的:单引号('),双引号("),反斜杠(\),和NULL  
  2. unction deal_quote($str){  
  3. if(get_magic_quotes_gpc()) {  
  4.     return stripslashes($str);  
  5. }  


I(函数)过滤器  htmlspecialchars() & (和号)" (双引号) ' (单引号) < (小于) > (大于)
php中过滤器  addslashes()  单引号('),双引号("),反斜杠(\),和NULL


参考内容

http://www.runoob.com/php/func-string-htmlspecialchars-decode.html

http://www.runoob.com/php/func-string-stripslashes.html

http://www.php100.com/html/php/hanshu/2013/0905/4689.html

http://www.runoob.com/php/func-string-addslashes.html


htmlspecialchars_decode()

 

定义和用法

htmlspecialchars_decode() 函数把一些预定义的 HTML 实体转换为字符。

会被解码的 HTML 实体是:

  • &amp; 解码成 & (和号)
  • &quot; 解码成 " (双引号)
  • ' 解码成 ' (单引号)
  • &lt; 解码成 < (小于)
  • &gt; 解码成 > (大于)

htmlspecialchars_decode() 函数是 htmlspecialchars() 函数的反函数。


语法

htmlspecialchars_decode(string,flags)


参数flags

  string 必需。规定要解码的字符串。
可选。规定如何处理引号以及使用哪种文档类型。

可用的引号类型:

  • ENT_COMPAT - 默认。仅解码双引号。
  • ENT_QUOTES - 解码双引号和单引号。
  • ENT_NOQUOTES - 不解码任何引号。

规定使用的文档类型的附加 flags:

  • ENT_HTML401 - 默认。作为 HTML 4.01 处理代码。
  • ENT_HTML5 - 作为 HTML 5 处理代码。
  • ENT_XML1 - 作为 XML 1 处理代码。
  • ENT_XHTML - 作为 XHTML 处理代码。

技术细节

返回值: 返回已转换的字符串。
PHP 版本: 5.1.0+
更新日志: 在 PHP 5.4 中,新增了用于规定使用的文档类型的附加 flags:ENT_HTML401、ENT_HTML5、ENT_XML1 和 ENT_XHTML。


addslashes()

 

定义和用法

addslashes() 函数返回在预定义的字符前添加反斜杠的字符串。

预定义字符是:

  • 单引号(')
  • 双引号(")
  • 反斜杠(\)
  • NULL

提示:该函数可用于为存储在数据库中的字符串以及数据库查询语句准备合适的字符串。

注释:默认情况下,PHP 指令 magic_quotes_gpc 为 on,对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。不要对已经被 magic_quotes_gpc 转义过的字符串使用 addslashes(),因为这样会导致双层转义。遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。


语法

addslashes(string)


参数

  string 必需。规定要转义的字符串。

技术细节

返回值: 返回已转义的字符串。
PHP 版本: 4+


addslashes()版本变化


magic_quotes_gpc函数在php中的作用是判断解析用户提示的数据,如包括有:post、get、cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误  

在magic_quotes_gpc=On的情况下,如果输入的数据有

单引号(’)、双引号(”)、反斜线()与 NUL(NULL 字符)等字符都会被加上反斜线。这些转义是必须的,如果这个选项为off,那么我们就必须调用addslashes这个函数来为字符串增加转义。

正是因为这个选项必须为On,但是又让用户进行配置的矛盾,在PHP6中删除了这个选项,一切的编程都需要在magic_quotes_gpc=Off下进行了。在这样的环境下如果不对用户的数据进行转义,后果不仅仅是程序错误而已了。同样的会引起数据库被注入攻击的危险。所以从现在开始大家都不要再依赖这个设置为On了,以免有一天你的服务器需要更新到PHP6而导致你的程序不能正常工作。

 代码如下 复制代码

当magic_quotes_gpc=On的时候,函数get_magic_quotes_gpc()就会返回1

当magic_quotes_gpc=Off的时候,函数get_magic_quotes_gpc()就会返回0

因此可以看出这个get_magic_quotes_gpc()函数的作用就是得到环境变量magic_quotes_gpc的值。既然在PHP6中删除了magic_quotes_gpc这个选项,那么在PHP6中这个函数我想也已经不复存在了。


php 判断是否开启get_magic_quotes_gpc功能了,以方便我们是否决定使用addslashes这个函数了。

 代码如下 复制代码

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;
}

预防数据库攻击的正确做法

 代码如下 复制代码

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”, “hello”, “321″);

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);

?>

posted on 2016-10-11 13:27  飘渺的悠远  阅读(2666)  评论(0编辑  收藏  举报