sql注入漏洞与防范
1建立查询语句
$host = "localhost"; $username = "root"; $dbname = "acool"; $dbpwd = "root"; $con = mysql_connect($host,$username,$dbpwd ) or die("#fail to contect to db."); mysql_select_db($dbname,$con) or die("fail to open database"); $user = $_GET['user']; $pwd = $_GET["pwd"]; $sql = "select * from user where username = '{$user}' and pwd = '{$pwd}' "; $result = mysql_query($sql,$con); $num_rows = mysql_num_rows($result); if($num_rows<1){ echo "fail"; }else{ echo "succes"; } while ($row = mysql_fetch_array($result)){ var_dump($row); } echo "<code>sql:$sql</code>"; //http://127.0.0.1/sql.php?user=admin&pwd=123456
当pwd密码不等于数据库的密码时.很明显利用1=1 恒成立
结果如下
显然sql语句是可以执行的
http://127.0.0.1/sql.php?user=admin&pwd=admin%20or%201=1
但客服端却没有输出任何结果 ?
由于引号导致sql构造不正确,需要绕过引号,让引号闭合;
failsql:select * from user where username = 'admin' and pwd = 'admin or 1=1'
http://127.0.0.1/sql.php?user=admin&pwd=admin' or '1=1
因此简单的mysql注入成功了
继续既然mysql这么有趣,还可以做些什么呢?
利用这个漏洞获取另一个表的数据
union 联合查询
因为union 联合查询的表字段必须相等,需要修改
select * from user where username = 'admin' and pwd = 'admin' UNION SELECT * ,1 FROM user_copy ;// 1充当一个字段,需要改变数量尝试
http://127.0.0.1/sql.php?user=admin&pwd=admin ' union SELECT * ,1 FROM user_copy where '1=1
这种构造sql 的select 语句外,构造insert ,delete语句
如何防范sql注入
1.如果是整型的变量或字段,使用intval()函数把所有的参数转化为一个数值,例如带参数的链接等
结果再次访问的结果
2.对一些字符类型的变量,用 addslashes (该字符串为了数据库查询语句等的需要在某些字符前加上了反斜线。这些字符是单引号(')、双引号(")、反斜线(\)与 NUL(NULL
字符)。)
3.利用PDO拓展参数绑定提供安全性
4.转义或过滤特殊字符如%