TypechoJoeTheme

至尊技术网

统计
登录
用户名
密码
/
注册
用户名
邮箱

悠悠楠杉

网站页面

PHP防止SQL注入

2021-08-14
/
0 评论
/
725 阅读
/
正在检测是否收录...
08/14

SQL注入的万能语句' or 1=1#

当我们在用户名处输入' or 1=1#,密码随便写,把它带入到语句中,就变成了

select * from user where uername='' or1=1#' and password='123456'

在SQL语句中#是注释符,所以后面的语句都会被注释掉

select * from user where username='' or1=1

也就是说可以用 'or 1=1# 这么一个字符串就可以绕开登录的密码,直接进入程序,防止这种情况出现,可以使用以下的预处理机制!

使用 PDO

1、通过传递一个插入值的数组执行一条预处理语句

$st = $db->prepare('select * from zz_order where id = ? and name = ?');
$st->execute([$id,$name]);// 成功时返回 true,失败时返回 false
$data = $st->fetch(PDO::FETCH_ASSOC);
print_r($data);

2、在 prepare 函数里面把参数用 ‘:name’ 这样的形式来替代,然后使用 execute 绑定参数。

$st = $db->prepare('select * from zz_order where id = :id');
$st->execute([':id' => $id]);
$data = $st->fetch(PDO::FETCH_ASSOC);
print_r($data);

3、通过绑定 PHP 变量执行一条预处理语句

$st = $db->prepare("select * from zz_order where id = ?");
$st->bindParam(1, $id);
$st->execute();
$data = $st->fetchAll(PDO::FETCH_ASSOC);
print_r($data);

使用 Mysqli

在 prepare 函数里面把参数用 ‘?’ 来替代,然后使用 bind_param 绑定参数。在 bind_param 中,第一个参数 's' 代表了参数的类型与个数(此处为一个字符串类型)。

$stmt = $db->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    // do something with $row
}

//bind_param参数类型
i - integer(整型)
d - double(双精度浮点型)
s - string(字符串)
b - BLOB(布尔值)

PDO

需要注意的是使用PDO去访问MySQL数据库时,真正的prepared statements默认情况下是不使用的。为了解决这个问题,你需要禁用模拟的prepared statements。下面是使用PDO创建一个连接的例子:

try {
    $db = new PDO('mysql:dbname=cs_cn;host=127.0.0.1;charset=utf8', 'root', 'root');
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);// 设置禁止本地模拟prepare
    //$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);// 设置捕获异常
} catch (PDOException $e) {
    die("Error!: " . $e->getMessage() . "<br/>");
}

ThinkPHP防止sql注入:https://www.zzwws.cn/archives/5488/

经验PHPMySQL防注入预处理
朗读
赞(1)
版权属于:

至尊技术网

本文链接:

https://www.zzwws.cn/archives/5551/(转载时请注明本文出处及文章链接)

评论 (0)