PHP安全与漏洞,防止SQL注入(一)

20 篇文章 0 订阅

什么是SQL注入

  • 首先是发生在Web程序中数据库层的安全漏洞,是网站存在最多最简单的漏洞。
  • 主要原因是程序对用户输入数据的合法性没有判断,导致攻击者可以再Web应用程序中事先定义好的SQL语句中添加额外的SQL语句,以此来实现欺骗数据库服务器执行SQL语句,属于非法操作。

SQL注入实例

比如登录界面,要求输入用户名和密码。
可以这样输入实现免账号登陆:

用户名: ‘or 1 = 1 –
密码:

点登录,如若没有特殊处理,这个非法用户就很得意的登录。
分析下原因,
理论登录时,后台会有一个认证程序,如下sql语句:

String sql = “select * from user_table where username=
’ “+userName+” ’ and password=’ “+password+” '”;

当输入了上面的用户名和密码,上面的SQL语句变成:

SELECT * FROM user_table WHERE username=
‘’or 1 = 1 – and password=’’

分析SQL语句:
条件后面username=”or 1=1 用户名等于 ” 或1=1 那么这个条件一定会成功;
然后后面加两个-,这意味着注释,它将后面的语句注释,让他们不起作用,这样语句永远都能正确执行,用户轻易骗过系统,获取合法身份。
这还是比较温柔的,如果是执行

SELECT * FROM user_table WHERE
username=’’ ;DROP DATABASE (DB Name) --’ and password=’’
….其后果可想而知…

解决方法

方法一:php.ini配置文件, 开启magic_quotes_gpc=on
  • PHP4.0及以上的版本中,该选项默认情况下是开启的。
  • 所以在PHP4.0及以上的版本中,就算PHP程序中的参数没有进行过滤,PHP系统也会对每一个通过GET、POST、COOKIE方式传递的变量自动转换,
  • 换句话说,输入的注入攻击代码将会全部被转换,将给攻击者带来非常大的困难。

虽然如此,攻击者仍然有机会进行SQL注入攻击

   实例演示:

    假设我们知道管理员的用户名为admin,密码不知道。并且已经将magic_quotes_gpc启用。

    SQL语句:sql="select∗fromuserswhereusername=sql="select∗fromuserswhereusername=name and password='pwd′";注意:变量pwd′";注意:变量name没加引号

    此时,在地址栏中输入username=admin%23,则合成后的sql语句为:

  select * from users where username='admin\' #' and password='';

  这时候通过url地址栏输入的单引号(’)将被加上反斜线,该sql语句将失效。

  admin转换成ASCII后是char(97,100,109,105,110)

  此时在地址栏中输入username=char(97,100,109,105,110)%23

  SQL语句就变成了:

  select * from users where username=char(97,100,109,105,110)#' and password='';

  执行结果为真,就可以顺利进入后台。

  对于数字型注入攻击,必须在任何的数字型参数放入数据库之前使用intval()对参数进行强制转换成数字,从而可以断绝数字型注入漏洞的产生。

  比如:id=intval(id=intval(_GET[‘id’]);

  select * from articles where id=’$id’;

  地址栏中输入:id=5’ or 1=1%23

  SQL语句将变成:select * from articles where id=’5’;

  而不是select * from articles where id=’5’ or 1=1#;
方法二,强制类型转换

在很多时候我们要用到类似xxx.php?id=xxx这样的URL,一般来说 i d 都 是 整 型 变 量 , 为 了 防 范 攻 击 者 把 id都是整型变量,为了防范攻击者把 idid篡改成攻击语句,我们要尽量强制变量,代码如下:

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

当然,还有其他的变量类型,如果有必要的话尽量强制一下格式。

方法三,输入内容验证

可以通过像单引号’,反斜杠\,字符or等敏感字符进行过滤,或者转义一些参数,从而破坏构造的sql语句,达到我们的目的呢。

<?php
$name=$_POST["userID"];
$passwd=$_POST["userPasswd"];

// 使用白名单进行输入用户名和密码验证
$whitepattern="/^[a-z\d]*$/i";         // 构造的白名单正则表达式,只允许输入的内容是字符串和数字的组合
$blackpattern="/\*|'|\"|#|;|,|or|\^|=|<|>|and/i";
// 构造的黑名单正则表达式
if(preg_match($blackpattern, $name)){ // preg_match:使用正则表达式对字符串进行正则匹配
	die('illegal input! 用户名中包含敏感词汇!');
}
if(!preg_match($whitepattern, $passwd)){
	die('illegal input! 密码中包含敏感词汇!');
}
?>

可以将该方法写在common文件里,多次调用更佳。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值