学习目标:
在这里收集总结一下常见漏洞的修复方案吧,给自己三天时间收集整理,尽量详细。
下面都是从
- 是什么
- 为什么
- 怎么做
参照:https://github.com/wooyunwang/Fortify
SQL注入漏洞
- 对用户输入的参数进行严格的过滤
- 将数据库里面的内容进行严格的加密
- 不要将数据库的错误查询进行回显
- 是用预编译,下面详细讲解一下预编译
预编译
- 什么是预编译
数据库接收到sql语句之后,需要词法和语义解析,优化sql语句,制定执行计划。这需要花费一些时间。但是很多情况,我们的一条sql语句可能会反复执行。在某种情况下,多条SQL语句都只有某些关键字不同。所以为了优化SQL语句的执行效率,所有产生了SQL预编译,当然这也成为了防止SQL注入的最好方式。预编译就是将这类语句的值用占位符代替:如下面的问号。
//赋值语句用?代替
string sql = "select id from users where username = ? and password= ?";
ps = connection.preparestatement(sql);
//在给?赋值之前,预编译就会把上面的语句送入数据库进行解析,如果没有
//错的话就会返回
//给?赋值
ps.setstring(1,tom);
ps.setstring(2,passwd);
resultset=psmt.executeQuery();
预编译语句被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行。
预编译是用过PreparedStatement和占位符来实现的。
-
为什么会防止SQL注入
使用预编译,而其后注入的参数将不会再进行SQL编译。也就是说其后注入进来的参数系统将不会认为它会是一条SQL语句,而默认其是一个参数,参数中的or或者and 等就不是SQL语法保留字了。
这最主要是由于不带占位符的拼接必须要用单引号’来包裹SQL字符串,而占位符的填写无需单引号,即使填入的变量是String str = “‘admin’”&#