php操作数据库防注入的方式有哪些

1.什么是SQL注入攻击?

百度百科:所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。

其实,我们可以简单的理解SQL注入为:未对用户输入进行过滤,导致用户的一些输入在程序执行时,当做SQL语句的一部分进行执行,从而针对一些敏感操作:OR 1=1 或者 WHERE 1=1 这种条件的加入,使得我们本身的SQL逻辑被跳过执行。

2.php5.x mysqli php预处理
PHP5.x开始引入了一种新的mysql操作方式-----mysqli,在php中也有一项相应的操作方式叫做PHP预处理。采用面向对象的方式来进行参数化绑定操作,由于对数据库操作的模式驱动不同,因此可以非常有效的防御sql注入。

php代码:

<!--?php

$root = "root";

$pwd = "root";

$host = "localhost";

$database =  "database";

$conn = new mysqli($host,$root,$pwd,$database);//面向对象的方式实例化一个对象

$keywords = $_GET['keywords'];

$search_sql = "select content from mykey where title = ? ";//其中的?是一个占位符

$search_action = $conn --->prepare($search_sql);//进行预处理操作

$search_action ->bind_param("s",$keywords);//绑定参数,第一个参数表示为上面预处理的的占位符的数量和每一个参数的数据类型,s为字符串,i为整形,d为双精度小数,有几个参数,就写几个s或d或i,比如说iiii,ssss,sidi这样的。然后后面就是有几个参数就写几个要绑定的变量,比如bind_param('sss',$username,$password,$code);

$search_action ->bind_result($content);//将结果绑定在相对应的变量上,比如你select了username,password,你就可以写bind_result($usernmae,$password);

$search_action ->execute();//执行sql操作

while($search_action ->fetch()){

echo $content.'<br>';

}

$search_action ->free_result();//释放内存

$search_action ->close();//结束这个实例化

?>
上面是php预处理中一个非常简单的例子,它内置的其他函数能很方便我们的开发速度,那么看到这里,很多人可能还是不明白,有人可能想问,你这个绑定参数是不是还是在拼凑sql语句?如果是拼凑语句,那还不是会产生注入吗?

 
这就要从他的操作原理来解释了,其实它在prepare操作中,就已经在数据库中,执行了语句,以后的绑定参数和执行,只不过是再传递数据进去而已,所以根本不会和sql语句拼接,也就自然不会将危险代码执行。因此,在这种模式下sql注入就能很有效的被防御了。

 

3.PHP通用SQL注入攻击方式

# step 1 SQL
SELECT * FROM users WHERE username = 'admin' AND password = 'e10adc3949ba59abbe56e057f20f883e'
# step 2 SQL
SELECT * FROM users WHERE username = 'admin'#' AND password = '96e79218965eb72c92a549dd5a330112'

其中第二步由于前台传入特殊字符单引号(')及#,在数据库中#为语句注释部分,则后续SQL语句不会被执行,可直接跳过我们的密码验证逻辑。

SELECT * FROM users WHERE username = 'admin' OR 1='1' AND password = '96e79218965eb72c92a549dd5a330112'

同样,我们使用此种方式可以达到跳过登录验证的目的

此类问题是未对用户输入的特殊字符进行过滤,如单引号('),双引号("),NULL等。PHP可以通过设置打开magic_quotes_gpc,自动针对特殊字符增加反斜线(\)的方式,对其进行转义,而避免被程序执行,当然,也可以利用以下方法针对未开启magic_quotes_gpc时,进行处理:
 

function addslashes_deep($value)
{
    if (empty($value))
    {
        return $value;
    }
    else
    {
        return is_array($value) ? array_map('addslashes_deep', $value) : addslashes($value);
    }
}
	
if(!get_magic_quotes_gpc())
{	
    $_POST = addslashes_deep($_POST);
    $_GET = addslashes_deep($_GET);
}

这样,上述经过处理的SQL语句如下:

SELECT * FROM users WHERE username = 'admin\' OR 1=\'1' AND password = '96e79218965eb72c92a549dd5a330112'

4.数字型SQL注入攻击

$id = $_GET['id'];	
$sql = "SELECT * FROM users WHERE id=".$id;
$res = $db->query($sql)->fetch_all();

/test.php?id=1 UNION SELECT 1,username,password,4,5,6,password,8,9,10,11 FROM users

浏览器地址栏输入如上地址,后台显示SQL如下:

SELECT * FROM users WHERE id=1 UNION SELECT 1,username,password,4,5,6,password,8,9,10,11 FROM users

我们通过这里很容易利用UNION命令,查询出用户名和密码等敏感信息

当然,此类防御也相当简单,对于整数型数据,我们在获取时,需要对其进行转化如下:

$id = intval($_GET['id'])

即可避免此类上述SQL注入

总结

通过以上两个示例,在PHP中,可以通过简单的三种方法来防御SQL注入:

①对用户的输入进行过滤处理后,在进行操作,如:addslashes()方法或者开启magic_quotes_gpc方法

②针对获取的数值型数据,进行二次转换,如intval(),floatval()

③所有需进行数据库查询的变量都使用单引号(')包围,如下:
 

$sql = "SELECT * FROM users WHERE username='".$username."'";
function pretty_print($array)
{
	echo '<pre>';
	print_r($array);
	echo '</pre>';
}
function addslashes_deep($value)
{
    if (empty($value))
    {
        return $value;
    }
    else
    {
        return is_array($value) ? array_map('addslashes_deep', $value) : addslashes($value);
    }
}
	
if(!get_magic_quotes_gpc())
{	
	$_POST = addslashes_deep($_POST);
	$_GET = addslashes_deep($_GET);
}
 
$db = mysqli_connect('127.0.0.1','root','root','mysqli_test');
 
$username = $_POST['username'];
$password = $_POST['password'];
 
$sql = "SELECT *".
       " FROM users".
       " WHERE username = '".$username.
       "' AND password = '".md5($password)."'";
	
 
$res = $db->query($sql)->fetch_row();
 
if(empty($res))
{
	echo '登录失败,用户名或密码不正确!';
}
else
{
	echo '登录成功,欢迎您:'.$res[1];
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值