最近总是看到有一些sql盲注得请求打到服务器上,请问如何防御这种攻击啊?
显然大家都知道参数化。那怎样才能做好参数化?如果你的查询不是复杂到非字符串构造sql不可(譬如递归或者动态层次的join),那几乎所有情况都可以使用下列方法解决:
1、SQLServer把数据跟stored procedure放在一起。其实这样还能起到数据和封装同步的作用,不需要两头改。在schema发生变化的时候,整个update都可以做transaction。
2、客户端(或者你的网站)只访问stored procedure。
3、只给你的客户端打开execute权限,这样它只能访问stored procedure。
使用stored procedure基本就等于让数据库来帮你做参数化,所以你不会犯任何错误。而且这个方法并不会在你需要字符串构造sql的时候发生问题,因为stored procedure里面也可以构造sql,而且做起这种sql构造的参数化也特别方便。
所有的注入问题都自动解决了。
我想,既然你已经了解到网站可能存在注入漏洞的危险,那么你一定已经了解注入的原理;因此,我觉得要是你不希望自己去考虑该怎么去过滤那些复杂精辟的注入语句的话,我觉得最好的方法是使用ORM,而不是使用老一套数据库查询方式!如果你使用的是java写后台的话,那么Hibernate会是比较值得尝试的框架!
菜鸟过来答一答:举个简单的sql注入的方式
//接收参数
String user=getParam(request,"user","");
String password=getParam(request,"pswd","");
//拼装sql
String checkSql="select * from user where username='"+user+"' and password ='"+password+"'";
//请求地址
String getUrl="xxx.jsp?user=admin&password=1' or '1'='1";
获取参数合成后的sql变成了
select * from users where userid='admin' and passwd='1' or '1'='1'
这条SQL将会返回所有users数据。也许你的接口就真的把这个user数据给返回过来了。
可注入的sql:
$id=$_REQUEST['id'];
$name=$_REQUEST['name'];
select * from members where id=$id;
select * from members where id='".$id."'";
select * from members where name='".$name."'";
不可注入:
select * from members where id='".intval($id)."'";
select * from members where name=".sql_escape($name);
使用JavaEE的PreparedStatement接口可以很方便的防止SQL注入,各个DataBase厂家的驱动都实现的不错。Druid这个连接池也有帮你过滤SQL,防止注入。jenkins可以配合一些插件,比如findBugs来查找有可能的SQL注入行为。
15 回答8.4k 阅读
8 回答6.2k 阅读
5 回答3.2k 阅读✓ 已解决
3 回答3.6k 阅读✓ 已解决
1 回答4k 阅读✓ 已解决
3 回答6k 阅读
2 回答2.8k 阅读✓ 已解决
WAF和OneRASP对SQL注入都很有效,WAF放在应用程序前面,可以通过匹配规则对SQL注入有比较好的防范,但是由于不知道SQL语句在应用程序里面具体是如何应用的,仅仅根据部分参数就判断是否是SQL注入,是不够的。这需要管理员对应用程序足够了解,针对应用程序做非常复杂的配置,这也造成误杀率比较高。
而OneRASP是将保护程序像疫苗注入到应用程序中,和应用程序一起运行,它熟悉应用程序的上下文,在JDBC的statement程序里进行保护,一方面它可以完整的看到整个SQL语句,同时它很清楚查出来的结果是什么。这样对于判断是否为注入就非常有根据。也使误杀率非常低。
OneRASP还有非常多的其他优点,有兴趣的同学请访问www.oneASP.com, 或者baidu一下。