失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 漏洞解决方案-SQL注入攻击

漏洞解决方案-SQL注入攻击

时间:2022-02-11 18:58:49

相关推荐

漏洞解决方案-SQL注入攻击

漏洞解决方案-SQL注入攻击

前置知识修复方案代码参考

前置知识

SQL注入攻击,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。


威胁描述:

如果SQL注入成功,攻击者可以获取系统数据库的信息,可以修改删除数据库,还可能获取执行命令的权限,进而完全控制服务器。

涉及功能点:

任何涉及数据库连接的功能点,如用户登录、查询、数据修改、删除等功能。

修复方案

防范SQL注入,标准方案为输入验证与参数化查询相结合。

输入验证分为白名单和黑名单两种方式,通常在系统中是结合到一起来完成输入验证,具体实现通过正则表达式来完成。需要注意以下几方面:

在可信系统(比如:服务器)上执行所有的数据验证。验证所有来自不可信数据源(比如:数据库,文件流,等)的数据。应当为应用程序应提供一个集中的输入验证机制和规则。为所有输入明确恰当的字符集,比如:UTF-8。在输入验证前,将数据按照常用字符进行编码(规范化)。如果进行关键字的验证,请先统一大小写。验证的不仅是参数,包含所有来自客户端的数据,包括:所有参数、URL、HTTP头信息(比如:cookie名字和数据值)。验证正确的数据类型、验证数据范围、验证数据长度。请考虑是否允许输入常见危险字符。部分常见的危险字符包括:< > " ’ % ( ) & + \ ’ " 。特殊字符单独验证:空字节 (%00);换行符 (%0d, %0a, \r, \n);路径替代字符“点-点-斜杠”(…/或…\)。验证替代字符:%c0%ae%c0%ae/ (使用规范化 验证双编码或其他类型的编码攻击)。

代码参考

安全开发实例:

使用特殊字符过滤程序防护SQL注入攻击:

代码功能:对HTTP请求中的所有参数进行危险字符过滤,发现危险字符可跳转到相应的错误页面。

public void doFilter(ServletRequest args0, ServletResponse args1,FilterChain chain) throws IOException, ServletException {HttpServletRequest req=(HttpServletRequest)args0;HttpServletResponse res=(HttpServletResponse)args1;//获得所有请求参数名Enumeration params = req.getParameterNames();String sql = "";while (params.hasMoreElements()) {//得到参数名String name = params.nextElement().toString();//得到参数对应值String[] value = req.getParameterValues(name);for (int i = 0; i < value.length; i++) {sql = sql + value[i];}}//有sql注入和XSS危险字符if (sqlValidate(sql)) {throw new IOException("您发送请求中的参数中含有非法字符:"+sql);//此处可根据系统实际情况进行统一的错误处理,可跳转到error.html} else {chain.doFilter(args0,args1);}}protected static boolean sqlValidate(String str) {str = str.toLowerCase(); //统一转为小写String badStr = "and|exec|insert|select|delete|update|count|union|master|truncate|char|declare|cast|set|fetch|varchar|sysobjects|drop|`|'|\"|<|>|(|)|/|\|=|+|-|#|*|;|%"; //过滤掉的sql注入和XSS的关键字,可以手动添加和修改String[] badStrs = badStr.split("\\|");for (int i = 0; i < badStrs.length; i++) {if (str.indexOf(badStrs[i]) >= 0) {return true; //参数中包含要过滤关键字;}}return false;//参数中不包含要过滤关键字;}

通过参数化查询方式进行SQL注入攻击防护:

String sql = “select * from product where cat=’?’ and price >’?’”; //创建包含参数占位符的SQL语句PreparedStatement pstmt = con.prepareStatement(sql);//创建PreparedStatement对象pstmt.setInt(1, request.getParameter(“cat”));//设置参数一类型和取值pstmt.setString(2, request.getParameter(“price”));//设置参数二类型和取值ResultSet rs = pstmt.executeQuery();//返回查询结果

使用MyBatis技术,通过Mapper.xml文件定义SQL语句进行SQL注入攻击防护:

<mapper namespace="TestUser">//命名空间<select id="getById" parameterType="java.lang.String"resultMap="TestFlowResult">select<include refid="TestFlowColumns" /><![CDATA[from TEST_TABLEwhereINSPECT_ID = #{id} ]]></select></mapper>

在编写mybatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击。

强类型的参数化查询,即在数据库增加、查询、更新操作时,sql语句中所有输入参数统一采用#param#方式。示例如下:

<update id="updatePtaskDetailState" parameterClass="java.lang.String">update ZX_PTASKDETAIL set BATCHJNLNOSTATE = '4' where JNLNO = #jnlNo#</update>

需要使用like语句的地方可以使用’%’||#param#||’%‘或concat(concat(’%’,#param#),’%’)避免注入。示例如下

select * from ZX_PCIF where name like '%'||#name#||'%'

关注公众号,一起分享实用安全技术,关注安全最新事件,记录工作常见问题,吐槽生活真心操蛋。

如果觉得《漏洞解决方案-SQL注入攻击》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。