文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

结合Mybatis聊聊对SQL注入的见解

2024-04-02 19:55

关注

Mybatis聊聊对SQL注入的见解

1.sql注入是什么

sql注入见名思意,是指一些非法用户通过将一些特殊字符或者sql语句插入到要提交的表单之中,从而让服务器在不知情的情况下执行恶意的sql命令,从而引发一系列的安全隐患。

讲的通俗一点就是说,用户利用sql语法将一些sql语句加在某些字段后面,提交表单的时候,服务器执行sql命令并未达到想要的结果反而引发异常和数据泄露。

这就是典型的系统漏洞,因此sql注入对系统的危害是非常大的,做好防止sql注入也是系统必须完善的。

2.sql注入实例

我写了个简单的登录程序,框架是Spring+SpringMVC+Mybatis。表结构如下:

(1)特殊符号,如 ' 和 .等

可以看到当我输入一个特殊符号,而后台未经过过滤的时候,便会抛出sql异常:

并且如果没有进行全局异常处理,用户便可以通过浏览器的开发者模式中获取到数据库和查询语句的相关信息。

而这个对系统来说是很危险的漏洞。

(2)sql语句的注入

当输入正确的账号密码的时候,可以看到执行时成功的。

但是如果加上这么一句sql语句在表单,我们可以看到结果依然可以执行成功

非法用户可以通过这个来测试数据库的表名字、该表的其他字段名、数据的量级等等。

举个例子:尝试获取到该表的其他字段名

只需要将刚才的表单中的“1=1”替换成测试sql语句即可,如果执行成功则代表该表中有这个字段存在。

看一下最后执行的sql语句:

就一目了然了。这通用是因为注入引起的。

类似的还有:'or''=' 不仅能执行成功,同时还有查询多全部的数据。

(3)通过sql语句的in和order by进行注入

以上的三点主要是因为在mybatis中使用了${}, sql语句没有执行预编译,无法防止sql注入。

3.mybatis框架下如何解决sql注入问题

mybatis框架本身就有防止sql注入的特性,这就要求我们必须在写sql语句时候遵循框架的书写规范。

(1)用#{param}替换所有的${param}

因为${}是拼接sql字符实现没有预编译的查询,因为是无法防御sql注入,而#{}则需要进行预编译,可以很大程度上防止sql注入。

在一些#{}使用时候会报错的地方,如like 查询、in 查询、order by排序等,

a) like:


select * from Users where username like '%${username}%'

替换成:


select * from Users where username like concat('%', #{username}, '%')

b) in


select * from Users where id in (${id})

替换成mybatis框架自带的foreach循环:

c) order by

不要直接使用:拼接排序

如:


select *from Users order by ${id}

而是在java层面做映射,然后用<if>来做判断

其他的类似的情况请按照相同的处理方式进行处理即可。

(2)对用户输入的数据进行sql注入校验

SqlServer本身的防sql注入机制,利用存储过程可以避免sql注入。应该禁止用户输入一些关键的特殊符号,如分号、分隔符、单引号等,同时对于一些关键位置进行sql关键字的屏蔽,如or、and等。必须对用户输入的内容的类型、长度、格式、范围进行校验。

(3)要对用户的权限进行区分

普通用户的权限和管理员的权限之间,必须严格区分开来,对管理员实现安全级别更高的验证,从而防止人为获取到更高权限时候的sql注入攻击。

(4)更高级别的验证

在后端代码和数据库中都开启对sql注入的验证,同时用专业的注入工具查找本系统的漏洞进行修复,也可以进行账号诱骗,将一些如“admin”之类的容易受到攻击的用户设置上千位的密码,让攻击者的软件因为解析量大而负载过大,从而耗尽资源而宕机。

一种常见的Mybatis的SQL注入

1.场景重现

现在有一张名为student的表,表结构如下:

在这里插入图片描述

其中id为自增主键,余下字段分别为英语成绩、数学成绩、美术成绩、学生的学号、学生的姓名、学生的电话。

目前表里面有6条数据:

在这里插入图片描述

2.代码展示

使用mybatis框架实现根据美术成绩查找相应的记录,在mapper.xml文件里,代码大概会这么写:


 <!--通过美术成绩作为筛选条件查询-->
    <select id="queryByArtGrade" resultMap="StudentMap">
        select
        id, english_grade, math_grade, art_grade, number, name, telephone
        from student
        <where>
            <if test="artGrade != null">
                and art_grade = #{artGrade}
            </if>
        </where>
    </select>

当然也可以这么写:


 <!--通过美术成绩作为筛选条件查询-->
    <select id="queryByArtGrade" resultMap="StudentMap">
        select
        id, english_grade, math_grade, art_grade, number, name, telephone
        from student
        <where>
            <if test="artGrade != null">
                and art_grade = ${artGrade}
            </if>
        </where>
    </select>

这两种写法的区别在于对传入参数的接收方式不同,前者是#{property},后者是${property}。

3.模拟请求&回应结果

想查询美术成绩为70的记录,使用postman进行请求,传入参数json为:

{

"artGrade":"70"

}

测试结果两者均为:

在这里插入图片描述

看起来好像是一样的结果,两种写法都正确。

但是我把参数改成下面的这个样子:

{

"artGrade":"'70' and id='4'"

}

结果就完全不同啦!

使用#{property}返回的结果为空:

在这里插入图片描述

通过日志,发现实际执行的SQL为:


select id, english_grade, math_grade, art_grade, number, name, telephone from classroom.student WHERE art_grade = "'70' and id='4'"

使用${property}返回的结果为一条:

在这里插入图片描述

通过日志,发现实际执行的SQL为:


select id, english_grade, math_grade, art_grade, number, name, telephone from classroom.student WHERE art_grade = '70' and id='4'

4.小结一下

这就是常见的sql注入了,因为后端接收传入参数的时候没有经过任何处理,直接到了mybatis层,而mybatis层接收参数的时候又使用了${property}这种方式,导致参数被直接拼接至预执行的SQL中,最后返回了一些恶意请求者需要的信息。

所以,mapper中尽量避免使用${property}来接收参数,因为你不知道上一层传进来的东西到底是什么。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯