mysql防注入方法_mybatis如何防止sql注入?mybatis 防止sql注入的方法介绍

在一些安全性要求很高的应用中(比如银行软件),经常使用将SQL语句全部替换为存储过程这样的方式,来防止SQL注入。这里就跟大家讲解一下mybatis如何防止sql注入和mybatis 防止sql注入的方法。

mybatis如何防止sql注入

7938614b9ea9323924cce5514051a284.png

mybatis如何防止sql注入?MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译,编译完成后的SQL:SELECT author,content FROM blog WHERE id = ?,传进来的id参数是一个整体,比如id='or 1=1',就查找不到。

在MyBatis中,“${xxx}”这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。但涉及到动态表名和列名(比如order by根据哪一列排序)时,只能使用“${xxx}”这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。

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

mybatis 防止sql注入的方法

SQL注入大多数也会比较清楚,就是SQL参数对应的字段值时插入混合SQL,如 ** username = or 1= 1** 这种,如果有更恶劣的,带上drop database 这种都是有可能的,所以一般SQL都会进行一定防注入处理,MyBatis其实用法大都清楚,就是**#{paras}和${paras}**两种用法,以前我就是会用,但是具体原理咱也没看过,在一次面试中,被别人问到过具体用法,注入原理,处理原理等等,当时就是根据自己的印象去回答了,但是对于MyBatis与数据库具体处理SQL注入却不是很熟悉的,这一节就来详细讲解下,记录一下。

#1. #{paras}与${paras}用法

对于**#{paras}和KaTeX parse error: Expected 'EOF', got '#' at position 23: …**写两个用法吧,一个根据**#̲{paras}**来查询,一种…{paras}**来查询,如下:

@ResultMap("BaseResultMap")@Select("select * from user where username = #{username}")User getUserByParas1(@Param("username") String username);@ResultMap("BaseResultMap")@Select("select * from user where username = ${username}")List getUserByParas2(@Param("username") String username);

调用这两个方法的程序为:

User user = userMapper.getUserByParas1("xiaxuan");List users = userMapper.getUserByParas2(" 1 or 1 = 1");System.out.println(user);System.out.println(users);

运行结果为:

11a0797ebdca6358c6ad1957e66e856b.png

运行结果和想象中差不多,在conf.xml中添加打印sql的配置.

再运行一次看看,如下图:

03e1a1b6ee805c7adbcec2c254623b7a.png

第一个sql是进行了占位符处理,第二个是直接拼出了sql语句。

上述就是演示#{paras}调用和和sql注入的过程,下面开始讲两者在实现过程中的原理。

2. 初始化源码分析

首先看看这两个方法是怎么加载的,这还是要回到注解方法的解析中,在前文中我们知在解析注解时,会将当前sql包装成SqlSource对象,然后在查询时使用,代码如下:

void parseStatement(Method method) { Class parameterTypeClass = getParameterType(method); LanguageDriver languageDriver = getLanguageDriver(method); SqlSource sqlSource = getSqlSourceFromAnnotations(method, parameterTypeClass, languageDriver); .....}

我们进getSqlSourceFromAnnotations方法中看看。

private SqlSource getSqlSourceFromAnnotations(Method method, Class parameterType, LanguageDriver languageDriver) { try { Class sqlAnnotationType = getSqlAnnotationType(method); Class sqlProviderAnnotationType = getSqlProviderAnnotationType(method); if (sqlAnnotationType != null) { if (sqlProviderAnnotationType != null) { throw new BindingException("You cannot supply both a static SQL and SqlProvider to method named " + method.getName()); } Annotation sqlAnnotation = method.getAnnotation(sqlAnnotationType); final String[] strings = (String[]) sqlAnnotation.getClass().getMethod("value").invoke(sqlAnnotation); return buildSqlSourceFromStrings(strings, parameterType, languageDriver); } else if (sqlProviderAnnotationType != null) { Annotation sqlProviderAnnotation = method.getAnnotation(sqlProviderAnnotationType); return new ProviderSqlSource(assistant.getConfiguration(), sqlProviderAnnotation, type, method); } return null; } catch (Exception e) { throw new BuilderException("Could not find value method on SQL annotation. Cause: " + e, e); } }

此处我们只分析带有@Select注解的方法,所有就是进入if条件中进行处理,这里再进入buildSqlSourceFromStrings方法。

private SqlSource buildSqlSourceFromStrings(String[] strings, Class parameterTypeClass, LanguageDriver languageDriver) { final StringBuilder sql = new StringBuilder(); for (String fragment : strings) { sql.append(fragment); sql.append(" "); } return languageDriver.createSqlSource(configuration, sql.toString().trim(), parameterTypeClass); }

最后通过languageDriver返回SqlSource,进入createSqlSource方法中。

@Override public SqlSource createSqlSource(Configuration configuration, String script, Class parameterType) { SqlSource source = super.createSqlSource(configuration, script, parameterType); checkIsNotDynamic(source); return source; }@Override public SqlSource createSqlSource(Configuration configuration, String script, Class parameterType) { // issue #3 if (script.startsWith("

3d4b8ff4e3a2165f51ba0821bafb4e6d.png

关于mybatis如何防止sql注入以及mybatis 防止sql注入的方法就为大家介绍到这里,MyBatis 是一种持久层框架,介于 JDBC 和 Hibernate 之间。通过 MyBatis 减少了手写 SQL 语句的痛苦,使用者可以灵活使用 SQL 语句,支持高级映射。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值