防止SQL注入

看韩顺平老师 数据库编程陷阱 视频讲座 笔记
--------------------------------------------------

SQL注入:

攻击:

$sql = "SELECT * FROM users WHERE
        username='$user' and passwd='$ps'";

万能用户名:

$user=bb' union select * from user (limit 1 或者 order by 之类的)/*

此时 SQL语句为

SELECT * FROM users WHERE
        username='bb' union select * from users/*' and passwd='$ps'

注: /* 表示后面的sql语句不执行 union 后面一定有值出现,所以此sql会有返回值

万能密码:

$pw=bb' or 1=1  或者 $pw = bb' union select * from user

如果PHP中书写sql语句时,变量值没有用单引号引起来,mysql会将变量值当成数值类型,很危险

防止:

1. 服务器
设置php.ini
把magic_quote_gpc设置为on(对单引号进行转译),display_errors设为off。
此时,原来的万能用户名和万能密码已无效,但还是能注入,因为 char(96)对应的是单引号,使用 char(96) 一样能注入

2.代码
 
方案 (1)
  密码比对: 通过用户输入的用户名查询数据库,如果得到密码,再与用户输入的密码相比对,如果相等,则正确
 

  方案(2)
  使用PDO (PHP Data Object)

 

<?php
//1.初始化一个PDO对象
$dsn='mysql:host=localhost;port=3306;dbname=text';
$user='root';
$pw='root';
$myPDO = new PDO($dsn,$user,$pw);

//2.设置编码
$myPDO->exec("set name utf8");

//3.预处理sql
$sql = 'select * from users where
        username=? and passwd=?';
$pdoStatment=$myPDO->prepare($sql);
//4.
$pdoStatment->execute(array($username,$passwd));

//5.
$res=$pdoStatment->fetch();
if(empty($res))
{
    //错误
}

?>

 

===============================================================

 另外一种 是用  mysql_real_escape_string

预防数据库攻击的正确做法:

<?php
function check_input($value)
{
    // 去除斜杠
    if (get_magic_quotes_gpc())
    {
        $value = stripslashes($value);
    }
    // 如果不是数字则加引号
    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
$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);
?>

 

 

posted @ 2012-12-09 13:05  梦话四叶  阅读(189)  评论(0编辑  收藏  举报