- mysql批量查询漏洞案例
(1) select * from user where id=1;
(2)select * from user where id=1 or 1=1;
分析: id=1条件只会查询一条,id=1 or 1=1会查询表中所有数据
示例代码:
// 数字注入
// select * from user where id = 1; // 正常需要
// select * from user where id = -1 or 1=1; // 异常构造
$config = include_once dirname(__FILE__).'/config.php';
// 获取网页传递过来的id
$id = isset($_GET['id'])?$_GET['id']:'';
$db = mysqli_connect($config['host'],$config['user'],$config['password'],$config['database']);
if(!$db){ die('数据库连接失败');}
mysqli_set_charset($db,'utf8');
/*
预防办法:
$id是整形,应该使用is_numeric对其进行判断,并且进行整形强转,如下
if(empty($id) || !is_numeric($id) ){
exit('id非法');
}
$id = (int)$id
*/
$sql = "select * from user where id = " . $id; ***// 此处没有对$id进行过滤,用户传入 1 or 1=1时,即可查询所有数据***
// 查询结果
$data = mysqli_query($db,$sql);
if(!$data){die('查询失败');}
$result = [];
// 循环打印结果
while ($row = mysqli_fetch_array($data,MYSQLI_ASSOC)){
$result[] = $row;
}
// 模拟登陆成功
echo '<pre>';
var_dump($result);
echo '</pre>';
mysqli_close($db);
2.登录免密案例
(1)select * from user where name=‘ajun’ and password=‘e10adc3949ba59abbe56e057f20f883e’;
(2)select * from user where name=‘ajun’ # and password=‘e10adc3949ba59abbe56e057f20f883e’;
(3)select * from user where name=‘ajun’-- and password=‘e10adc3949ba59abbe56e057f20f883e’;
第(2)和第(3)中,#号和–分别将SQL语句后面and password=‘e10adc3949ba59abbe56e057f20f883e’;注释掉,实际SQL只执行 select * from user where name=‘ajun’,从而避免密码条件查询
代码案例:
// select * from user where name = 'ajun' and password = 'e10adc3949ba59abbe56e057f20f883e'; // 正常需要
// select * from user where name = 'ajun' # and password = 'e10adc3949ba59abbe56e057f20f883e'; // 异常构造1
// select * from user where name='ajun'-- and password='e10adc3949ba59abbe56e057f20f883e'; // 异常构造2
$config = include_once dirname(__FILE__) . '/config.php';
$name = isset($_POST['name']) ? $_POST['name'] : '';
$password = isset($_POST['password']) ? $_POST['password'] : '';
if(empty($name) || empty($password)){ exit('用户名或密码不能为空');}
/*
// 预防1
$name = addslashes($name);
$password = addslashes($password);
// 预防2:正则表达式
if (!preg_match("/^[a-zA-Z0-9]{6,20}$",$name)){ exit('用户名非法');}
// 预防3:mysql预编译机制
*/
$db = mysqli_connect($config['host'], $config['user'], $config['password'], $config['database']);
if (!$db) {exit('数据库连接失败');}
mysqli_set_charset($db, "utf8");
$sql = "select * from user where name='" . $name . "' and password='" . md5($password) . "'"; // 此处,没有对$name进行过滤,用户传入的$name值为 ajun'# 或者 ajun'-- 时,SQL将会注释掉 and password='" . md5($password) . "'",使得SQL语句变成 select * from user where name = 'ajun';
$data = mysqli_query($db, $sql);
if (!$data) { exit('数据查询失败' . mysqli_error($db));}
$result = [];
while ($row = mysqli_fetch_array($data, MYSQLI_ASSOC)) {
$result[] = $row;
}
if (!$result) {
$test = '登陆失败';
} else {
$test = '登陆成功';
echo '<pre>';
var_dump($result);
echo '</pre>';
}
echo '</br>';
echo $test;
echo '</br>';
mysqli_close($db);