假设我们的用户表中存在一行.用户名字段为username.值为aaa.密码字段为pwd.值为pwd..

下面我们来模拟一个用户登录的过程..

<?php
$username = "aaa";
$pwd = "pwd";
$sql = "SELECT * FROM table WHERE username = '{$username}' AND pwd = '{$pwd}'";
echo $sql; //输出 SELECT * FROM table WHERE username = 'aaa' AND pwd = 'pwd'
?>

 

这样去执行这个sql语句.显然是可以查询出来东西的.返回用户的这一列.登录成功!!
然后我改一下..把密码改一下.随便一个值.如下.我改成了ppp.

<?php
$pwd = 'ppp';
$sql = "SELECT * FROM table WHERE username = '{$username}' AND pwd = '{$pwd}'";
echo $sql; //输出 SELECT * FROM table WHERE username = 'aaa' AND pwd = 'ppp'
?>

  

这样很显然.如果去执行这个SQL语句..是查询不到东西的.也就是密码错误.登录失败!!
但是有的人总是不老实的.他们会想尽一切办法来进行非法的登录.所谓非法就是在他不知道用户名密码的时候进行登录.并且登录成功..
那么他们所做的原理是什么呢??其实原理都是利用SQL语句..SQL语句强大的同时也给我们带来了不少麻烦..
我来举个最简单的例子.我们要运用到的SQL关键字是or
还是上面的代码.我们只要修改一下密码即可

<?php
$username = "aaa";
$pwd = "fdsafda' or '1'='1"; //前面的密码是瞎填的..后来用or关键字..意思就是无所谓密码什么都执行
$sql = "SELECT * FROM table WHERE username = '{$username}' AND pwd = '{$pwd}'";
echo $sql; //输出 SELECT * FROM table WHERE username = 'aaa' AND pwd = 'fdsafda' or '1'='1'
?>

  

执行一下这个SQL语句..可怕的事情发生了..竟然可以查询到这一行数据..也就是登录成功了..
这是多么可怕的事情..

SQL注入演示教程,见博文:http://blog.csdn.net/wusuopubupt/article/details/8818996

PHP为了解决这个问题.magic_quotes state..就是PHP会自动过滤传过来的GET.POST等等.
题外话.实践证明这个东西是畸形的..大部分程序不得不为判断此功能而耗费了很多代码..
Java中可没有这个东西..那么Java中如何防止这种SQL注入呢??

Java的sql包中提供了一个名字叫PreparedStatement的类.
这个类就是我要说的绑定参数!
什么叫绑定参数??我继续给大家举例..(我用PHP举例)

<?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'
?>

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

转于http://blog.csdn.net/wusuopubupt/article/details/9668501

mysql绑定参数bind_param原理以及防SQL注入的更多相关文章

  1. [转载]mysql绑定参数bind_param原理以及防SQL注入

    假设我们的用户表中存在一行.用户名字段为username.值为aaa.密码字段为pwd.值为pwd.. 下面我们来模拟一个用户登录的过程.. <?php $username = "aa ...

  2. 回头探索JDBC及PreparedStatement防SQL注入原理

    概述 JDBC在我们学习J2EE的时候已经接触到了,但是仅是照搬步骤书写,其中的PreparedStatement防sql注入原理也是一知半解,然后就想回头查资料及敲测试代码探索一下.再有就是我们在项 ...

  3. 【荐】PDO防 SQL注入攻击 原理分析 以及 使用PDO的注意事项

    我们都知道,只要合理正确使用PDO,可以基本上防止SQL注入的产生,本文主要回答以下几个问题: 为什么要使用PDO而不是mysql_connect? 为何PDO能防注入? 使用PDO防注入的时候应该特 ...

  4. golang 防SQL注入 基于反射、TAG标记实现的不定参数检查器

    收到一个任务,所有http的handler要对入参检查,防止SQL注入.刚开始笨笨的,打算为所有的结构体写一个方法,后来统计了下,要写几十上百,随着业务增加,以后还会重复这个无脑力的机械劳作.想想就l ...

  5. PDO防 SQL注入攻击 原理分析 以及 使用PDO的注意事项

    我们都知道,只要合理正确使用PDO(PDO一是PHP数据对象(PHP Data Object)的缩写),可以基本上防止SQL注入的产生,本文主要回答以下几个问题: 为什么要使用PDO而不是mysql_ ...

  6. mysql之数据库连接的方法封装及防sql注入

    一.定义数据库和表 create database animal; CREATE TABLE `pet` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `name ...

  7. JDBC及PreparedStatement防SQL注入

    概述 JDBC在我们学习J2EE的时候已经接触到了,但是仅是照搬步骤书写,其中的PreparedStatement防sql注入原理也是一知半解,然后就想回头查资料及敲测试代码探索一下.再有就是我们在项 ...

  8. PHP防SQL注入不要再用addslashes和mysql_real_escape_string

    PHP防SQL注入不要再用addslashes和mysql_real_escape_string了,有需要的朋友可以参考下. 博主热衷各种互联网技术,常啰嗦,时常伴有强迫症,常更新,觉得文章对你有帮助 ...

  9. Sqlparameter防SQL注入

    一.SQL注入的原因 随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对 ...

随机推荐

  1. 【mysql】mysql front 提示Access violation at address 010C9CD0 in module ‘mysql-front.exe’

    1 错误描述: 利用mysql-front 工具新建数据库.提示了一下错误 2 解决办法: 内存越界问题,最好重新注册下Windows的动态链接库 首先“开始”—“cmd” 在打开的dos窗口中运行

  2. Mahout实现基于用户的协同过滤算法

    Mahout中对协同过滤算法进行了封装,看一个简单的基于用户的协同过滤算法. 基于用户:通过用户对物品的偏好程度来计算出用户的在喜好上的近邻,从而根据近邻的喜好推测出用户的喜好并推荐. 图片来源 程序 ...

  3. ubuntu 14.04 返回到经典桌面方法

    1.打开终端,运行下面命令:sudo apt-get install gnome-session-fallback 2.重启机器,选择gnome,然后登录

  4. web移动端一些常用知识

    1.去掉 a,input 在移动端浏览器中的默认样式(半透明灰色遮罩阴影) a,button,input,optgroup,select,textarea { -webkit-tap-highligh ...

  5. pandas处理日期时间,按照时间筛选

    pandas有着强大的日期数据处理功能,本期我们来了解下pandas处理日期数据的一些基本功能,主要包括以下三个方面: 按日期筛选数据 按日期显示数据 按日期统计数据 运行环境为 windows系统, ...

  6. 使用angular路由切换后 轮播以及iscrollJs失效的问题

    我们在使用angular的时候,路由总是最让人头疼的地方. 在这里为大家解决一些用angular来回切换遗留下的小问题 比如我们在使用ng-route时如果主页面含有轮播图,当你切换到其他页面再切回主 ...

  7. 棋盘游戏---hdu1281(最大匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1281   题目大意:就是车和车之间不能发生攻击.还有一部分位置不可以放置棋子.   解题思路:一行一列 ...

  8. ajax请求,html调用js

    1:html中调用js中的函数,js使用ajax请求向后台请求,返回数据. <!DOCTYPE html> <html lang="en"> <hea ...

  9. MonkeyScript使用教程

    原文地址https://www.cnblogs.com/yizhou-xu/p/8072813.html 原文地址https://www.cnblogs.com/YatHo/p/7205162.htm ...

  10. 4.9 Routing -- Query Parameters

    一.概述 1. 在URL中查询参数是可选的key-value对,出现在?的右边.例如,下面的URL有两个查询参数,sort和page,对应的值分别是ASC和2. example:http://exam ...