Java如何有效避免SQL注入漏洞的方法总结

作者:LiveEveryDay 时间:2021-11-22 07:01:54 

1、简单又有效的方法是使用PreparedStatement

采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX(如:setString)方法传值即可。

好处:

(1).代码的可读性和可维护性变好。

(2).PreparedStatement尽最大可能提高性能。

(3).最重要的一点是极大地提高了安全性。

原理:

SQL注入只对SQL语句的编译过程有破坏作用,而PreparedStatement的SQL语句编译阶段已经准备好了,执行阶段只是把输入串作为数据处理,而不再对SQL语句进行解析、准备,因此也就避免了SQL注入问题。

一些热门ORM框架在处理SQL时候也都使用了PreparedStatement,比如MyBatis。

我们在使用MyBatis要注意:在注入参数值得时候使用#{xxx},#{xxx}已经启用了预编译功能,在SQL执行前,会先将上面的SQL发送给数据库进行编译;执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题。

“${xxx}”这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。

有时有些操作要使用这种方式,比如传入表,模糊匹配等。这时可以使用bind+#{}防止SQL注入(#{}进行预编译,传递的参数不进行编译,只作为参数,相当于PreparedStatement)。

bind元素可以从OGNL表达式中创建一个变量并将其绑定到上下文。比如:

<select id="selectBlog" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG WHERE title LIKE #{pattern}
</select>

2、使用过滤器

如果我们做不到所有的SQL语句都使用PreparedStatement,我们可以使用过滤器,进行全局的拦截这些字符串。在过滤器中,使用正则表达式过滤传入的参数。使用正则表达式,判断是否匹配:

String begin="您的请求参数信息";

//可以通过配置文件,去配置这些特殊字符,以便随时添加一些关键字。
String pattern="|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|char|declare|sitename|net user|xp_cmdshell|;|or|-|+|,|like";

Pattern r = Pattern.compile(pattern);
Matcher isMatch = r.matcher(begin);
if(isMatch.find()){
   //危险请求参数
}

防止sql注入的一些建议

1. 代码层防止sql注入攻击的最佳方案就是sql预编译

public List<Course> orderList(String studentId){
   String sql = "select id,course_id,student_id,status from course where student_id = ?";
   return jdbcTemplate.query(sql,new Object[]{studentId},new BeanPropertyRowMapper(Course.class));
}

这样我们传进来的参数 4 or 1 = 1就会被当作是一个student_id,所以就不会出现sql注入了。

2. 确认每种数据的类型,比如是数字,数据库则必须使用int类型来存储

3. 规定数据长度,能在一定程度上防止sql注入

4. 严格限制数据库权限,能最大程度减少sql注入的危害

5. 避免直接响应一些sql异常信息,sql发生异常后,自定义异常进行响应

6. 过滤参数中含有的一些数据库关键词

来源:https://blog.csdn.net/troubleshooter/article/details/122274026

标签:java,sql,注入
0
投稿

猜你喜欢

  • Java8深入学习系列(一)lambda表达式介绍

    2021-08-20 11:23:19
  • C#将Sql数据保存到Excel文件中的方法

    2023-11-11 08:34:26
  • java网络编程基础知识介绍

    2023-01-10 20:37:44
  • Java 数据结构之删除链表中重复的结点

    2023-11-28 15:36:22
  • C#实现程序等待延迟执行的方法

    2023-07-16 06:32:36
  • unity里获取text中文字宽度并截断省略的操作

    2023-11-02 07:48:52
  • SpringBoot接口如何统一异常处理

    2023-08-10 15:06:20
  • spring aop execution表达式的用法

    2023-08-22 05:39:24
  • MyBatis配置的应用与对比jdbc的优势

    2023-08-27 07:03:47
  • C语言实现线性表的基本操作详解

    2022-02-24 22:08:32
  • Spring Boot中配置定时任务、线程池与多线程池执行的方法

    2021-08-08 13:31:30
  • Android12 蓝牙适配的实现步骤

    2021-08-25 08:36:34
  • 详解JAVA中的Collection接口和其主要实现的类

    2021-06-20 19:14:08
  • Android 获取屏幕的多种宽高信息的示例代码

    2021-07-10 06:07:10
  • 如何使用mybatis-generator自动生成代码

    2022-08-17 07:12:19
  • 详解java模板和回调机制

    2023-08-13 15:33:46
  • 详解Android应用中DialogFragment的基本用法

    2022-02-24 05:41:46
  • Java如何使用Query动态拼接SQL详解

    2022-12-31 09:40:14
  • SpringBoot超详细讲解@Value注解

    2022-03-06 12:05:36
  • WPF MVVM示例讲解

    2022-04-16 22:47:20
  • asp之家 软件编程 m.aspxhome.com