php 防注入的一些总结

一、几个与特殊字符处理有关的PHP函数

 函数名 释义 介绍
htmlspecialchars将与、单双引号、大于和小于号化成HTML格式&转成& 
"转成"
' 转成'
<转成&lt;
>转成&gt;
htmlentities()所有字符都转成HTML格式除上面htmlspecialchars字符外,还包括双字节字符显示成编码等。
   
addslashes单双引号、反斜线及NULL加上反斜线转义被改的字符包括单引号 (')、双引号 (")、反斜线 backslash (\) 以及空字符NULL。
stripslashes去掉反斜线字符去掉字符串中的反斜线字符。若是连续二个反斜线,则去掉一个,留下一个。若只有一个反斜线,就直接去掉。
   
quotemeta加入引用符号将字符串中含有 . \\ + * ? [ ^ ] ( $ ) 等字符的前面加入反斜线 "\" 符号。
nl2br()将换行字符转成<br> 
strip_tags去掉HTML及PHP标记去掉字符串中任何 HTML标记和PHP标记,包括标记封堵之间的内容。注意如果字符串HTML及PHP标签存在错误,也会返回错误。
mysql_real_escape_string转义SQL字符串中的特殊字符转义 \x00  \n  \r  空格  \  '  " \x1a,针对多字节字符处理很有效。mysql_real_escape_string会判断字符集,mysql_escape_string则不用考虑。

下面针对常用表单特殊字符处理进行总结:

测试字符串:

$dbstr='D:\test
<a href="http://www.metsky.com">http://www.metsky.com</a>,天缘博客
\'!=\'1\' OR \'1\'
</DIV>
<script  language="javascript" type="text/javascript">alert("Fail");</script>


<?php echo "<br/>PHP OUTPUT"; ?>';

测试代码:

 header("Content-Type: text/html; charset=UTF-8");
echo "------------------------------------------------------<br/>\r\n";
echo  $dbstr."<br/>\r\n------------------------------------------------------<br/>\r\n";
$str=fnAddSlashes($_POST['dd']);
echo $str."<br/>\r\n------------------------------------------------------<br/>\r\n";

$str = preg_replace("/\s(?=\s)/","\\1",$str);//多个连续空格只保留一个
$str = str_replace("\r","<br/>",$str);
$str = str_replace("\n","<br/>",$str);
$str = preg_replace("/((<br\/?>)+)/i", "<br/>", $str);//多个连续<br/>标签只保留一个

$str=stripslashes($str);
echo strip_tags($str)."<br/>\r\n------------------------------------------------------<br/>\r\n";
echo htmlspecialchars($str)."<br/>\r\n------------------------------------------------------<br/>\r\n";
echo htmlentities($str)."<br/>\r\n------------------------------------------------------<br/>\r\n";
echo mysql_escape_string($str)."<br/>\r\n------------------------------------------------------<br/>\r\n";

字符串包含:反斜杠路径,单双引号,HTML标记、链接、未封堵的HTML标记,数据库语法容错,JS执行判断,PHP执行判断,多个连续回车换行符和空格。其中有些概念有包含关系,下同。

源码输出如下(会执行JS脚本):

二、表单提交数据处理

1、强制加入反斜线

由于有些主机默认开启魔术引用get_magic_quotes_gpc,有些可能关闭,所以在程序上最好一律强制加入反斜线,这样可以统一处理,字符涉及单引号、双引号和反斜线。

function fnAddSlashes($data)
{
    if(!get_magic_quotes_gpc()) //只对POST/GET/cookie过来的数据增加转义
        return is_array($data)?array_map('addslashes',$data):addslashes($data);
    else
        return $data;
}

使用函数fnAddSlashes($data);结果如下图(不会执行JS脚本,但HTML、JS和PHP标记仍需容错处理):

使用stripslashes、换行替换、空格替换后结果如下图:

2、对特殊字符处理

以下是几个常用字符串处理,可以视具体情况取舍。由于上面已经对提交表单数据进行一次转义,所以如果需要对内容替换或过滤需要考虑addslashes对相关字符的影响,替换或查找时需考虑反斜杠的添加。其它字符替换不影响,比如\r\n替换。

A、多个连续空格只保留一个

$data = preg_replace("/\s(?=\s)/","\\1",$data );//多个连续空格只保留一个

B、回车换行替换成<br/>
$data = str_replace("\r","<br/>",$data );
$data = str_replace("\n","<br/>",$data );

//html中默认<br>没封堵,xhtml中<br/>有封堵,建议使用<br/>,更多区别:http://stackoverflow.com/questions/1946426/html-5-is-it-br-br-or-br

C、多个连续<br/>只保留一个

$data = preg_replace("/((<br\/?>)+)/i", "<br/>", $data );//多个连续<br/>标签只保留一个
 

D、全部过滤HTML标记

该方式是全部过滤潜在危险的标记,包括HTML、链接、未封堵HTML标记、JS、PHP。

使用函数strip_tags($data)

该函数使用后会过滤全部的HTML标记(包括链接)和PHP标记、JS代码等,其中链接会保留链接原文只是去除<a>标记和href部分内容,PHP标记和JS标记则会整体去除,包括中间的内容,如下图:

E、不过滤标记,只是把他们HTML化

该方法是把原提交内容全部按照普通文本来处理。

使用函数htmlspecialchars($data),该函数执行后会把提交数据全部按照普通文本来展示,如下图:

使用htmlentities函数执行结果(中文显示乱码):

三、写入数据库

由于使用addslashes($data)后对于高级的可信任用户可以直接写入数据库,但是addslashes无法拦截使用0xbf27代替的单引号,所以最好还是使用mysql_real_escape_string或mysql_escape_string进行转义,不过转义之前需先去除反斜杠(假设已默认开启addslashes)。

function fnEscapeStr($data)

{

if (get_magic_quotes_gpc())
{
        $data= stripslashes($value);
}
$data="'". mysql_escape_string($value) ."'";
return $data;
}

$data=fnEscapeStr($data);

执行后如下图:

四、提交后的即时显示

1、如果上文使用了addslashes,则必须在把数据回显之前去除反斜线

使用函数stripslashes($data)

注意这个函 数只是面向被addslashes($data)处理后的数据,要谨慎使用,否则会导致反斜线丢失(比如内容的文件夹路径分割线、驱动器路径等),天缘前几天出现的错误就是因为在数据库读取时使用了这个函数(代码是老代码,忘记修改了)导致再次写入数据库导致很多路径中的反斜杠丢失,要不也没有本文了。

2、使用函数htmlspecialchars($data),该函数执行后会把提交数据全部按照文本来展示,除非允许链接等需特殊处理外,可以一律使用 htmlspecialchars输出,尤其是对于未封堵的HTML标记,如果既没有过滤再不采用标记转换,那么输出后可能会导致版面混乱。

htmlentities则不建议使用,一方面对输出的源码造成很大的阅读障碍,再者使用htmlentities函数会造成双字节字符比如中文会显示一堆乱码。其它字符显示还算正常。



转载自 天缘博客 http://www.metsky.com/archives/377.html

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值