php mysql_real_escape_string addslashes及mysql绑定参数防SQL注入攻击


Posted in PHP onDecember 23, 2016

php mysql_real_escape_string addslashes及mysql绑定参数防SQL注入攻击

php防止SQL注入攻击一般有三种方法:

  1. 使用mysql_real_escape_string函数
  2. 使用addslashes函数
  3. 使用mysql bind_param()

本文章向大家详细介绍这三个方法在防止SQL注入攻击中的效果及区别。

mysql_real_escape_string防sql注入攻击

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。

在有些时候需要将mysql_real_escape_string与mysql_set_charset一起使用,因为如果不指定编码,可能会存在字符编码绕过mysql_real_escape_string函数的漏洞,比如:

$name=$_GET['name'];
$name=mysql_real_escape_string($name);
$sql="select *from table where name like '%$name%'";

当输入name值为name=41%bf%27%20or%20sleep%2810.10%29%3d0%20limit%201%23时,sql语句输出为:

SELECT * FROM table WHERE name LIKE '%41¿\\\' or sleep(10.10)=0 limit 1#%';

这时候引发SQL注入攻击。

下面是mysql_real_escape_string函数防止SQL注入攻击的正确做法:

<?php
function check_input($value)
{
// 去除斜杠
if (get_magic_quotes_gpc())
 {
 $value = stripslashes($value);
 }
// 如果不是数字则加引号
/* http://www.manongjc.com/article/1242.html */
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
mysql_set_charset('utf-8');
$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);
?>

addslashes防sql注入攻击

国内很多PHP coder仍在依靠addslashes防止SQL注入(包括我在内),我还是建议大家加强中文防止SQL注入的检查。addslashes的问题在于可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,成为一个有效的多字节字符,其中的0xbf5c仍会被看作是单引号,所以addslashes无法成功拦截。当然addslashes也不是毫无用处,它可用于单字节字符串的处理。

addslashes会自动给单引号,双引号增加\,这样我们就可以安全的把数据存入数据库中而不黑客利用,参数'a..z'界定所有大小写字母均被转义,代码如下:

echo addcslashes('foo[ ]','a..z'); //输出:foo[ ] 
$str="is your name o'reilly?"; //定义字符串,其中包括需要转义的字符 
echo addslashes($str); //输出经过转义的字符串

mysql bind_param()绑定参数防止SQL注入攻击

什么叫绑定参数,给大家举个例子:

<?php  
$username = "aaa";  
$pwd = "pwd";  
$sql = "SELECT * FROM table WHERE username = ? AND pwd = ?";  
bindParam($sql, 1, $username, 'STRING'); //以字符串的形式.在第一个问号的地方绑定$username这个变量  
bindParam($sql, 2, $pwd, 'STRING');    //以字符串的形式.在第二个问号的地方绑定$pwd这个变量  
echo $sql;  
?>

你肯定不知道会输出什么..更无法知道绑定参数有什么好处!这样做的优势是什么.更不知道bindParam这个函数到底做了什么.

下面我简单的写一下这个函数:

<?php  
/**  
 * 模拟简单的绑定参数过程  
 *  
 * @param string $sql  SQL语句  
 * @param int $location 问号位置  
 * @param mixed $var   替换的变量  
 * @param string $type  替换的类型  
 */ 
$times = 0;  
//这里要注意,因为要“真正的"改变$sql的值,所以用引用传值 
function bindParam(&$sql, $location, $var, $type) {  
  global $times;  
  //确定类型  
  switch ($type) {  
    //字符串  
    default:          //默认使用字符串类型  
    case 'STRING' :  
      $var = addslashes($var); //转义  
      $var = "'".$var."'";   //加上单引号.SQL语句中字符串插入必须加单引号  
      break;  
    case 'INTEGER' :  
    case 'INT' :  
      $var = (int)$var;     //强制转换成int  
    //还可以增加更多类型..  
  }  
  //寻找问号的位置  
  for ($i=1, $pos = 0; $i<= $location; $i++) {  
    $pos = strpos($sql, '?', $pos+1);  
  }  
  //替换问号  
  $sql = substr($sql, 0, $pos) . $var . substr($sql, $pos + 1);  
}  
?>

注:由于得知道去除问号的次数..所以我用了一个global来解决.如果放到类中就非常容易了.弄个私有属性既可

通过上面的这个函数.我们知道了..绑定参数的防注入方式其实也是通过转义进行的..只不过是对于变量而言的..

我们来做一个实验:

<?php  
$times = 0;  
$username = "aaaa";  
$pwd = "123";  
$sql = "SELECT * FROM table WHERE username = ? AND pwd = ?";  
bindParam($sql, 1, $username, 'STRING'); //以字符串的形式.在第一个问号的地方绑定$username这个变量  
bindParam($sql, 2, $pwd, 'INT');    //以字符串的形式.在第二个问号的地方绑定$pwd这个变量  
echo $sql; //输出 SELECT * FROM table WHERE username = 'aaaa' AND pwd = 123  
?>

可以看到.生成了非常正规的SQL语句.那么好.我们现在来试下刚才被注入的那种情况

<?php  
$times = 0;  
$username = "aaa";  
$pwd = "fdsafda' or '1'='1";  
$sql = "SELECT * FROM table WHERE username = ? AND pwd = ?";  
bindParam($sql, 1, $username, 'STRING'); //以字符串的形式.在第一个问号的地方绑定$username这个变量  
bindParam($sql, 2, $pwd, 'STRING');    //以字符串的形式.在第二个问号的地方绑定$pwd这个变量  
echo $sql; //输出 SELECT * FROM table WHERE username = 'aaa' AND pwd = 'fdsafda\' or \'1\'=\'1'  
?>

可以看到.pwd内部的注入已经被转义.当成一个完整的字符串了..这样的话.就不可能被注入了.

 总结:

上面三个方法都可以防止sql注入攻击,但第一种方法和第二种方法都存在字符编码的漏洞,所以本文章建议大家使用第三种方法。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

PHP 相关文章推荐
PHP has encountered an Access Violation
Jan 15 PHP
php随机输出名人名言的代码
Oct 07 PHP
利用php实现禁用IE和火狐的缓存问题
Dec 03 PHP
PHP时间戳与日期之间转换的实例介绍
Apr 19 PHP
基于PHP中的常用函数回顾
Jul 11 PHP
PHP实现通过正则表达式替换回调的内容标签
Jun 15 PHP
thinkphp实现163、QQ邮箱收发邮件的方法
Dec 18 PHP
PHP使用stream_context_create()模拟POST/GET请求的方法
Apr 02 PHP
PHP实现的常规正则验证helper公共类完整实例
Apr 27 PHP
PHP简单实现二维数组赋值与遍历功能示例
Oct 19 PHP
浅谈PHP中pack、unpack的详细用法
Mar 12 PHP
php+Ajax处理xml与json格式数据的方法示例
Mar 04 PHP
php的4种常用运行方式详解
Dec 22 #PHP
php curl 模拟登录并获取数据实例详解
Dec 22 #PHP
使用PHP连接多种数据库的实现代码(mysql,access,sqlserver,Oracle)
Dec 21 #PHP
Docker配置PHP开发环境教程
Dec 21 #PHP
PHP符合PSR编程规范的实例分享
Dec 21 #PHP
利用PHP生成CSV文件简单示例
Dec 21 #PHP
PHP实现支付宝即时到账功能
Dec 21 #PHP
You might like
一个简单计数器的源代码
2006/10/09 PHP
PHP读取txt文件的内容并赋值给数组的代码
2011/11/03 PHP
PHP操作Memcache实例介绍
2013/06/14 PHP
基于jquery的tab切换 js原理
2010/04/01 Javascript
Zero Clipboard实现浏览器复制到剪贴板的方法(多个复制按钮)
2016/03/24 Javascript
js自定义QQ菜单效果
2017/01/10 Javascript
Node.js查找当前目录下文件夹实例代码
2017/03/07 Javascript
Bootstrap模态框(Modal)实现过渡效果
2017/03/17 Javascript
JavaScript实现区块链
2018/03/14 Javascript
Vue.set()动态的新增与修改数据,触发视图更新的方法
2018/09/15 Javascript
vue2.0+vue-router构建一个简单的列表页的示例代码
2019/02/13 Javascript
详解如何探测小程序返回到webview页面
2019/05/14 Javascript
解决VUE mounted 钩子函数执行时 img 未加载导致页面布局的问题
2020/07/27 Javascript
通过高德地图API获得某条道路上的所有坐标用于描绘道路的方法
2020/08/24 Javascript
[15:09]DOTA2国际邀请赛采访专栏:Loda
2013/08/06 DOTA
python实现去除下载电影和电视剧文件名中的多余字符的方法
2014/09/23 Python
用实例分析Python中method的参数传递过程
2015/04/02 Python
python使用multiprocessing模块实现带回调函数的异步调用方法
2015/04/18 Python
Python2.7基于笛卡尔积算法实现N个数组的排列组合运算示例
2017/11/23 Python
python 借助numpy保存数据为csv格式的实现方法
2018/07/04 Python
解决csv.writer写入文件有多余的空行问题
2018/07/06 Python
Python实现繁体中文与简体中文相互转换的方法示例
2018/12/18 Python
Tensorflow分类器项目自定义数据读入的实现
2019/02/05 Python
python+selenium实现简历自动刷新的示例代码
2019/05/20 Python
pandas按行按列遍历Dataframe的几种方式
2019/10/23 Python
python实现数字炸弹游戏
2020/07/17 Python
如何用Python编写一个电子考勤系统
2021/02/08 Python
HTML5进阶段内联标签汇总(小篇)
2016/07/13 HTML / CSS
贪睡宠物用品:Snoozer Pet Products
2020/02/04 全球购物
研发工程师的岗位职责
2013/11/18 职场文书
英文自荐信格式
2013/11/28 职场文书
工程项目经理任命书
2014/06/05 职场文书
文体活动总结
2015/02/04 职场文书
2015暑期社会实践调查报告
2015/07/14 职场文书
美德少年事迹材料(2016推荐版)
2016/02/25 职场文书
Debian11 Xfce终端光标的颜色怎么设置?
2022/08/14 数码科技