SQL防注入总结

0x00 背景

自己一个人学了这么久的web安全,感觉需要一些总结,加上今天下午电话面试总被问到的问题,自己总结了一下写出来和大家分享。(小白一个,也算自己记录一下,大佬勿喷)

0x01SQL注入实例

这里就以DVWA来做个示范,毕竟主要讲防御

low等级的注入无过滤直接提交id

LOW SQL

medium等级使用了mysqli_real_escape_string函数进行转义,被转义的包括\x00,\n,\r,\,’,”,\x1a(参考菜鸟教程)但是这种简单的转义很容易就被各种编码方式绕过。

MEDIUM SQL

high等级的代码采用了窗口跳转的方式,但是对于上交的数据始终没有处理就提交了,只是简单的在其后加了一个LIMIT 1,来限制取数据的行数,但是只要简单的使用#或者--+来注释掉就可以了。(感觉这个应该属于midium)

HIGH SQL

high等级的代码加入了token机制和PDO,基本防御了SQL注入。反正以我的水平和在网上查找的资料来看,好像没有成功注入的。

HIGH SQL

0x02

首先大前提是验证都处于服务器端,前端的验证形同虚设。

(1)使用PDO

PDO是PHP的一个扩展,为PHP访问数据库提供一个统一的接口,这就表明PDO可以连接不同类型的数据库系统,但是我们还是需要自己编写SQL语句。PDO随PHP5.1发行,在PHP5.0的PECL扩展中也可以使用,无法运行于之前的PHP版本,可以在phpinfo()中查看是否支持PDO。

$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root');//设置编码以防止乱码

$sql ="SELECT id FROM user WHERE email=:email";

$stmt = $pdo->prepare($sql);

$email = filter_input(INPUT_GET,'email');

$stmt->bindValue(':email', $email);

上述代码中,:email是具名占位符,可以安全的绑定任意值。预处理语句会自动过滤$email的值,防止数据库收到SQL注入攻击。一个sql语句字符串中可以绑定多个具名占位符,然后在预处理语句中通过bindValue()方法绑定各个占位符的值。

(2)使用mysqli_query

MySQLi 扩展是在 PHP 5.0.0 版本中引进的,且只针对mysql数据库,但是其实大概原理和DBO相似,都是采用了prepare + bind 的写法。

$mysqli = new mysqli('localhost','username','password','database');  

$query = $mysqli->prepare('  

   SELECT * FROM users  

   WHERE username = ?  

   AND email = ?  

   AND last_login > ?'); 

$query->bind_param('sss', 'test', $mail, time() - 3600);  

$query->execute();

这个问号(?)绑定参数看上去很短,但是相比名称式参数缺少了灵活性,而且迫使开发者必须保证参数的顺序,有时候让人觉得很蛋疼。而且不幸的是MySQLi并不支持名称式参数。

(3)对输入进行转义处理

这一类主要是通过编程语言的预定义函数对输入转义,包括mysql_real_escape_string、addslashes()等,但是这一类函数存在一定的安全风险,不推荐使用。参见文章:PHP防SQL注入不要再用addslashes和mysql_real_escape_string了

(4)限制输入的内容

这其中包括对select、union等的过滤,但是这样一方面带来了对于用户使用的舒适性也有可能过滤不严格导致形同虚设。

(5)对输入编码

//这也算是一种处理各种注入的万能方法了,但是不足就是每次存取都需要编码或者解密,效率可能会降低。

SELECT password FROM users WHERE name = 'root'            --普通方式  

SELECT password FROM users WHERE name = 0x726f6f74        --防止注入  

SELECT password FROM users WHERE name = UNHEX('726f6f74') --防止注入  

(6)使用存储过程

存储过程是各种数据库的一种函数式编程方法,类似于预处理,只分配必要的数据库许可权限,有助于减轻SQL注入的影响——限制攻击者只能调用存储过程,从而限制了能够访问或修改的数据。由于SQL注入不仅能发生在应用层,还能发生在数据库层,因此如果攻击者将恶意语句写入到存储过程中,虽然访问和修改数据受到限制,但是如果在后续的动态SQL中使用了该输入,仍可能造成SQL注入。

以上就是目前我能知道的所有了,需要学习的还很多。FIGHTING~~~

如果谁看到我这个觉得不深入,给大家推荐一篇更详细的文章:SQL注入之代码层防御

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Web安全简史 在Web1.0时代,人们更多是关注服务器端动态脚本语言的安全问题,比如将一个可执行脚本(俗称Web...
    潘良虎阅读 3,964评论 3 72
  • Welcome 目前网络上充斥着大量的陈旧信息,让PHP新手误入歧途,传播着错误的实践和糟糕的代码,这必须得到纠正...
    layjoy阅读 21,760评论 7 118
  • 注入攻击 OWASP将注入攻击和跨站脚本攻击(XSS)列入网络应用程序十大常见安全风险。实际上,它们会一起出现,因...
    OneAPM阅读 2,629评论 1 15
  • 六项精进打卡格式 姓名:张人杰 日精进打卡第40天 【打卡始于2017.10.14持续于2017.11....
    上善若水心静思锐阅读 196评论 1 2
  • 一一得一、一二得二、一三得三……七七四十九……八九七十二、九九八十一 01 前几天,陈可辛导演的《三分钟》火遍朋友...
    令子呀阅读 500评论 5 3