php 过滤所有html标签

 更新时间:2016年11月25日 15:25  点击:1909

首先我们推荐filter_sanitize_string ,filter_sanitize_string 过滤器去除或编码不需要的字符。

这个过滤器删除那些对应用程序有潜在危害的数据。它用于去除标签以及删除或编码不需要的字符。

name: "string"
id-number: 513
可能的选项或标志:

filter_flag_no_encode_quotes - 该标志不编码引号
filter_flag_strip_low - 去除 ascii 值在 32 以下的字符
filter_flag_strip_high - 去除 ascii 值在 32 以上的字符
filter_flag_encode_low - 编码 ascii 值在 32 以下的字符
filter_flag_encode_high - 编码 ascii 值在 32 以上的字符
filter_flag_encode_amp - 把 & 字符编码为 &

*/

$var="<b>bill gates<b>";

var_dump(filter_var($var, filter_sanitize_string));

/*
第二个函数strip_tags
strip_tags() 函数剥去 html、xml 以及 php教程 的标签。

语法
strip_tags(string,allow)
*/

echo strip_tags("hello <b>world!</b>");

//hello world!

function uh($str)
{
    $farr = array(
        "/s+/",                                                                    
                       //过滤多余的空白
        "/<(/?)(script|i?frame|style|html|body|title|link|meta|?|%)([^>]*?)>/isu",
  //过滤 <script 等可能引入恶意内容或恶意改变显示布局的代码,如果不需要插入flash等,还可
以加入<object的过滤
        "/(<[^>]*)on[a-za-z]+s*=([^>]*>)/isu",                                     
//过滤网页特效的on事件
     
   );
   $tarr = array(
        " ",
        "<123>",           //如果要直接清除不安全的标签,这里可以留空
        "12",
   );

  $str = preg_replace( $farr,$tarr,$str);
   return $str;
}

更多详细内容请查看:http://www.111cn.net/phper/19/70dd2a905e74cefc9be9c0f17268dadc.htm
?>

由于php教程和mysql教程本身得原因,php+mysql的注射要比asp教程困难,尤其是注射时语句的构造方面更是个难点,本文主要是借对okphp bbs v1.3一些文件得简单分析,来谈谈php+mysql注射语句构造方式,希望本文对你有点帮助。
  声明:文章所有提到的“漏洞”,都没有经过测试,可能根本不存在,其实有没有漏洞并不重要,重要的是分析思路和语句构造。
二.“漏洞”分析:
  1.admin/login.php注射导致绕过身份验证漏洞:
  代码:
  
代码

  $conn=sql_connect($dbhost, $dbuser, $dbps教程wd, $dbname);  $password = md5($password);  $q = "select id,group_id from $user_table where username='$username' and password='$password'";  $res = sql_query($q,$conn);  $row = sql_fetch_row($res);  $q = "select id,group_id from $user_table where username='$username' and password='$password'
 

  中
  $username 和 $password 没过滤,很容易就绕过。(php100中文网)
  对于select * from $user_table where username='$username' and password='$password'这样的语句改造的方法有:
  构造1(利用逻辑运算):$username=' or 'a'='a $password=' or 'a'='a

  相当于sql语句:

select * from $user_table where username='' or 'a'='a' and password='' or 'a'='a'


 

  构造2(利用mysql里的注释语句# ,/* 把$password注释掉):$username=admin'#(或admin'/*)

  即: 

select * from $user_table where username='admin'#' and password='$password'
  相当于:

select * from $user_table where username='admin'


 

  在admin/login.php中$q语句中的$password在查询前进行了md5加密所以不可以用构造1中的语句绕过。这里我们用构造2:

  select id,group_id from $user_table where username='admin'#' and password='$password'"

  相当于: 

select id,group_id from $user_table where username='admin'


 

1.如果动态构造的sql语句中包含参数,请必须对参数做如下操作
a.将'(单引号)替换成''(两个单引号)
b.将--(注释符)替换掉
c.将参数加入语句时,一定要在前后各加上引号,如:'select * from table where id='''+@id+''''这样的加法
2.如果动态构造的sql语句中包含表参数,请勿必给表加上[](中括号),如:'select * from ['+@tab+']'这样的做法

3..避免动态sql语句:尤其是从ie客户端获取查询、修改、删除条件的字段最容易被注入,例如上述从客户端获取personid,为了开发方便,直接把从客户端获取的persongid作为sql语句的条件,却没有对personid作必要的检查,所以在开发时执行sql语句时最好使用preparedstatement类。

 

4.  验证数据:在客户端ie使用网页特效验证用户输入数据的合法性作用其实不是很大,一定要在获取客户端数据之后,对数据进行严格的验证,开发人员不要假想用户只会输入合法的数据。确保在应用程序中检查分号、引号、括号、sql关键字等。可以使用正则表达式来进行复杂的模式匹配,运用它可以达到良好的效果。


×××网站地址薄查看程序需要传递一个personid,personid可以通过url参数传递,由于地址本查看程序直接获取personid,没有做任何数据合法性验证,而且personid是字符串变量,获取personid的代码如下:

if (getparameter(req,"personid")!=null){

personid=getparameter(req,"personid").trim();

}else{

personid="";

}

该程序中组合成的动态sql语句如下:

personsql="select * from 表名 where userid="+long.tostring(userid)+" and addrcontactid="+personid;

 

由于程序没有检查personid是否是整数,所以攻击者随便给personid赋一个值,即可继续运行后续的程序逻辑,如果攻击者输入如下网址:

http://www.----------------------?personid=6414 or 2=2

组合成的sql语句如下:

select * from 表名where userid=1433620 and addrcontactid=6414 or 2=2

防范方法

  sql注入漏洞可谓是“千里之堤,溃于蚁穴”,这种漏洞在网上极为普遍,通常是由于程序员对注入不了解,或者程序过滤不严格,或者某个参数忘记检查导致。在这里,我给大家一个函数,代替asp教程中的request函数,可以对一切的sql注入say no,函数如下:

function saferequest(paraname,paratype)
 '--- 传入参数 ---
 'paraname:参数名称-字符型
 'paratype:参数类型-数字型(1表示以上参数是数字,0表示以上参数为字符)

 dim paravalue
 paravalue=request(paraname)
 if paratype=1 then
  if not isnumeric(paravalue) then
   response.write "参数" & paraname & "必须为数字型!"
   response.end
  end if
 else
  paravalue=replace(paravalue,"'","''")
 end if
 saferequest=paravalue
end function

上面函数应用

对于int型的参数,如文章的id等,可以先判断是不是整数。

id =trim(request("id"))
if id<>"" then
  if not isnumeric(id) then
    response.write"请提供数字型参数"
    response.end
  end if
  id = clng(id)
else
  response.write"请输入参数id"
  response.end
end if


<?php教程
require_once(dirname(__file__)."/../include/common.inc.php");
if(emptyempty($dopost))
{
$dopost = "";
}
if($dopost=="rename")
{
if(rename('dedesql.query.php','arc.sqlquery.class.php')){
echo "成功!";
}else{
echo "失败!";
}
exit();
}
if($dopost=="viewinfo")
{
if(emptyempty($tablename))
{
echo "没有指定表名!";
}
else
{
$dsql->setquery("show create table ".$dsql->dbname.".".$tablename);
$dsql->execute('me');
$row2 = $dsql->getarray('me',mysql教程_both);
$ctinfo = $row2[1];
echo "<xmp>".trim($ctinfo)."</xmp>";
}
exit();
}
if($dopost=="index")
{
require_once(dedeinc.'/arc.partview.class.php');
$envs = $_sys_globals = array();
$envs['aid'] = 0;
$pv = new partview();
$row = $pv->dsql->getone('select * from `#@__homepageset`');
$templet = str_replace("{style}",$cfg_df_style,$row['templet']);
$homefile = dirname(__file__).'/'.$row['position'];
$homefile = str_replace("//","/",str_replace("","/",$homefile));
$fp = fopen($homefile,'w') or die("无法更新网站主页到:$homefile 位置");
fclose($fp);
$tpl = $cfg_basedir.$cfg_templets_dir.'/'.$templet;
$pv->settemplet($tpl);
$pv->savetohtml($homefile);
$pv->close();
echo "成功更新首页!";
exit();
}
else if($dopost=="query")
{
$sqlquery = trim(strips教程lashes($sqlquery));
if(eregi("drop(.*)table",$sqlquery) ||eregi("drop(.*)database",$sqlquery))
{
echo "<span style='font-size:10pt'>删除'数据表'或'数据库教程'的语句不允许在这里执行。</span>";
exit();
}
if(eregi("^select ",$sqlquery))
{
$dsql->setquery($sqlquery);
$dsql->execute();
if($dsql->gettotalrow()<=0)
{
echo "运行sql:{$sqlquery},无返回记录!";
}
else
{
echo "运行sql:{$sqlquery},共有".$dsql->gettotalrow()."条记录,最大返回100条!";
}
$j = 0;
while($row = $dsql->getarray())
{
$j++;
if($j>100)
{
break;
}
echo "<hr size=1 width='100%'/>";
echo "记录:$j";
echo "<hr size=1 width='100%'/>";
foreach($row as $k=>$v)
{
echo "<font color='red'>{$k}:</font>{$v}<br/>rn";
}
}
exit();
}
if($querytype==2)
{
$sqlquery = str_replace("r","",$sqlquery);
$sqls = split(";[ t]{0,}n",$sqlquery);
$nerrcode = "";$i=0;
foreach($sqls as $q)
{
$q = trim($q);
if($q=="")
{
continue;
}
$dsql->executenonequery($q);
$errcode = trim($dsql->geterror());
if($errcode=="")
{
$i++;
}
else
{
$nerrcode .= "执行: <font color='blue'>$q</font> 出错,错误提示:<font color='red'>".$errcode."</font><br>";
}
}
echo "成功执行{$i}个sql语句!<br><br>";
echo $nerrcode;
}
else
{
$dsql->executenonequery($sqlquery);
$nerrcode = trim($dsql->geterror());
echo "成功执行1个sql语句!<br><br>";
echo $nerrcode;
}
exit();
}
if($dopost=="view")
{
;echo '<html>
<head>
<meta http-equiv='content-type' content='text/html; charset=gb2312'>
<title>sql命令行工具</title>
<link href='img/base.css教程' rel='stylesheet' type='text/css'>
</head>
<body background='img/allbg.gif' leftmargin='8' topmargin='8'>
<table width="98%" border="0" align="center" cellpadding="3" cellspacing="1" bgcolor="#d1ddaa">
<tr>
<td height="19" background="img/tbg.gif">
<table width="96%" border="0" cellspacing="1" cellpadding="1">
<tr>
<td width="24%"><strong>sql命令运行器:</strong></td>
<td width="76%" align="right"> <b><a href="sys_data.php"><u>数据备份</u></a></b>
| <b><a href="sys_data_revert.php"><strong><u>数据还原</u></strong></a></b>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td height="200" bgcolor="#ffffff" valign="top">
<table width="100%" border="0" cellspacing="4" cellpadding="2">
<form action="" method="post" name="infoform" target="stafrm">
<input type='hidden' name='dopost' value='viewinfo' />
<tr bgcolor="#f3fbec">
<td width="15%" height="24" align="center">系统的表信息:</td>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="35%">
<select name="tablename" id="tablename" style="width:100%" size="6">
';
$dsql->setquery("show tables");
$dsql->execute('t');
while($row = $dsql->getarray('t',mysql_both))
{
$dsql->setquery("select count(*) from ".$row[0]);
$dsql->execute('n');
$row2 = $dsql->getarray('n',mysql_both);
$dd = $row2[0];
echo " <option value='".$row[0]."'>".$row[0]."(".$dd.")</option>rn";
}
;echo ' </select>
</td>
<td width="2%"> </td>
<td width="63%" valign="bottom">
<div style="float:left;margin-right:20px;">
<input type="submit" name="submit1" value="优化选中表" class="coolbg np" onclick="this.form.dopost.value='opimize';" />
<br />
<input type="submit" name="submit2" value="修复选中表" class="coolbg np" onclick="this.form.dopost.value='repair';" style="margin-top:6px;" />
<br />
<input type="submit" name="submit3" value="查看表结构" class="coolbg np" onclick="this.form.dopost.value='viewinfo';" style="margin-top:6px;" />
</div>
<div style="float:left">
<input type="submit" name="submit5" value="优化全部表" class="coolbg np" onclick="this.form.dopost.value='opimizeall';" />
<br />
<input type="submit" name="submit6" value="修复全部表" class="coolbg np" onclick="this.form.dopost.value='repairall';" style="margin-top:6px;" />
</div>
</td>
</tr>
</table></td>
</tr>
<tr>
<td height="200" align="center">返回信息:</td>
<td>
<iframe name="stafrm" frameborder="0" id="stafrm" width="100%" height="100%"></iframe>
</td>
</tr>
</form>
<form action="" method="post" name="form1" target="stafrm">
<input type='hidden' name='dopost' value='query'>
<tr>
<td height="24" colspan="2" bgcolor="#f3fbec"><strong>运行sql命令行:
<input name="querytype" type="radio" class="np" value="0">
单行命令(支持简单查询)
<input name="querytype" type="radio" class="np" value="2" checked>
多行命令</strong></td>
</tr>
<tr>
<td height="118" colspan="2">
<textarea name="sqlquery" cols="60" rows="10" id="sqlquery" style="width:90%"></textarea>
</td>
</tr>
<tr>
<td height="53" align="center"> </td>
<td>
<input name="imagefield" type="image" src="img/button_ok.gif" width="60" height="22" border="0" class='np' />
</td>
</tr>
</form>
</table>
</td>
</tr>
</table>
</body>
</html>
';}
?>

1. php 配置文件 php.ini 中的 magic_quotes_gpc 选项没有打开,被置为 off
  2. 开发者没有对数据类型进行检查和转义
  不过事实上,第二点最为重要。我认为, 对用户输入的数据类型进行检查,向 mysql教程 提交正确的数据类型,这应该是一个 web 程序员最最基本的素质。但现实中,常常有许多小白式的 web 开发者忘了这点, 从而导致后门大开。
  为什么说第二点最为重要?因为如果没有第二点的保证,magic_quotes_gpc 选项,不论为 on,还是为 off,都有可能引发 sql 注入攻击。下面来看一下技术实现:
 一. magic_quotes_gpc = off 时的注入攻击
  magic_quotes_gpc = off 是 php 中一种非常不安全的选项。新版本的 php 已经将默认的值改为了 on。但仍有相当多的服务器的选项为 off。毕竟,再古董的服务器也是有人用的。
  当magic_quotes_gpc = on 时,它会将提交的变量中所有的 '(单引号)、"(双号号)、(反斜线)、空白字符,都为在前面自动加上 。下面是 php 的官方说明:

复制代码 代码如下:
magic_quotes_gpc boolean

sets the magic_quotes state for gpc (get/post/cookie) operations. when magic_quotes are on, all ' (single-quote), " (double quote), (backslash) and nul's are escaped with a backslash automatically

如果没有转义,即 off 情况下,就会让攻击者有机可乘。以下列测试脚本为例:
复制代码 代码如下:

<?
if ( isset($_post["f_login"] ) )
{
// 连接数据库教程...
// ...代码略...

// 检查用户是否存在
$t_struname = $_post["f_uname"];
$t_strpwd = $_post["f_pwd"];
$t_strsql = "select * from tbl_users where username='$t_struname' and password = '$t_strpwd' limit 0,1";

if ( $t_hres = mysql_query($t_strsql) )
{
// 成功查询之后的处理. 略...
}
}
?>

<html><head><title>sample test</title></head>
<body>
<form method=post action="">
username: <input type="text" name="f_uname" size=30><br>
password: <input type=text name="f_pwd" size=30><br>

<input type="submit" name="f_login" value="登录">
</form>
</body> 

 

[!--infotagslink--]

相关文章