sql注入的两种防御方法

一.使用预编译语句,变量绑定

以php语言为例


<?php
header('Content-type:text/html; charset=UTF-8');
$username = isset($_GET['username']) ? $_GET['username'] : '';
$userinfo = array();
if($username){
	//使用mysqli驱动连接demo数据库
	$mysqli = new mysqli("localhost", "root", "root", 'demo');
	//使用问号替代变量位置
	$sql = "SELECT uid,username FROM user WHERE username=?";
	$stmt = $mysqli->prepare($sql);
	//绑定变量
	$stmt->bind_param("s", $username);
	$stmt->execute();
	$stmt->bind_result($uid, $username);
	while ($stmt->fetch()) {
	    $row = array();
	    $row['uid'] = $uid;
	    $row['username'] = $username;
	    $userinfo[] = $row;
	}
}
echo '<pre>',print_r($userinfo, 1),'</pre>';

使用了预编译语句后,数据库对其进行了语法分析,优化sql语句,制定执行计划,作用如下:

1.有效防止sql注入攻击。用户传入的参数用占位符?代替,当语句真正运行时,传过来的参数只会被看成纯文本,不会重新编译,不会被当做sql指令。从根本上防止了用户直接与数据库进行交互。

2.提升性能。一次编译、多次运行,越复杂的sql语句,编译的复杂度将越大,预编译阶段可以合并多次操作为一个操作,省去了解析优化等过程,可以提升性能。

二.密码”加盐“

通常,开发者会使用不可逆加密(例如md5)对用户的信息进行保护,如下

<?php
//用户注册时候设置的password
$password = $_POST['password'];
//md5加密,传统做法直接将加密后的字符串存入数据库
$passwordmd5 = md5($password)

从这句代码可以看到采用了md5的不可逆加密算法来存储密码,这也是多年来业界常用的密码加密算法,但是这仍然不安全。为什么呢?

这是因为md5加密有一个特点:同样的字符串经过md5哈希计算之后生成的加密字符串也是相同的,由于业界采用这种加密的方式由来已久,黑客们也准备了自己强大的md5彩虹表来逆向匹配加密前的字符串,这种用于逆向反推MD5加密的彩虹表在互联网上随处可见,在Google里使用md5 解密作为关键词搜索,一下就能找到md5在线破解网站,当然也并不是每一个都能成功,但可以肯定的是,这个彩虹表会越来越完善。

所以,我们有迫切的需求采用更好的方法对密码数据进行不可逆加密,通常的做法是为每个用户确定不同的密码加盐(salt)后,再混合用户的真实密码进行md5加密,如以下代码:

<?php
//用户注册时候设置的password
$password = $_POST['password'];
//md5加密,传统做法直接将加密后的字符串存入数据库,但这不够,我们继续改良
$passwordmd5 = md5($password);
//为用户生成不同的密码盐,算法可以根据自己业务的需要而不同
$salt = substr(uniqid(rand()), -6);
//新的加密字符串包含了密码盐
$passwordmd5 = md5($passwordmd5.$salt);

参考文章:
链接:https://www.zhihu.com/question/22953267/answer/80141632

链接:https://blog.csdn.net/qq_43936524/article/details/115104527

posted @ 2021-07-11 17:33  追寻_smile  阅读(1073)  评论(0)    收藏  举报