美文网首页安全
浅谈SQL注入以Mybatis为例

浅谈SQL注入以Mybatis为例

作者: 微博云玩家 | 来源:发表于2018-11-06 15:35 被阅读181次

最近在工作室的分享会上准备了SQL注入的内容,到这里记录下。

首先,第一个问题:什么是SQL注入?

百度百科的解释是:所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

从字面上来看就是在web页面上提交一些会涉及到数据库操作的数据时,在数据中提交一些SQL命令,尝试欺骗数据库系统,让其运行插入进去的自定义的SQL语句。

举个例子来看:

Mybatis mapper层具体实现的SQL语句

这里是mybatis中一个查找接口的SQL实现

通过postman访问接口来间接调用这个实现:

postman访问接口间接调用mybatis的测试结果

可以看到name参数那里的值为不正常的数据,但是同样找到了id为6的用户信息,这是为什么呢?

这就是SQL注入:通过在提交的name数据里加入SQL语句使得之前的SQL语句:

SELECT ID,USERNAME,PASSWORD,AGE FROM USER WHERE ID=${arg0} AND USERNAME=${arg1}

在实际运行时成为了:SELECT ID,USERNAME,PASSWORD,AGE FROM USER WHERE ID=6 AND USERNAME=1 OR 1=1

因为1=1始终为true,所以我可在不知道id为6的username信息时就能获取到他的账号信息。

那么第二个问题:SQL注入的危害?

从上面的例子就可以看出,通过SQL注入,我们可以在没有数据库权限的情况下,对数据库进行操作,比如获取数据库数据,删除某个表等等。

最后一个问题:如何防止SQL注入?

这里我们还是以Mybatis为例:

Mybatis防止SQL注入

将SQL实现部分修改为如上图所示,然后我们再测试一遍:

防止SQL注入测试

可以看到,用同样的方式调用接口时,就无法获取到id为6的账号信息了。那么是哪个部分防止了SQL注入呢,对比两个SQL实现的截图可以发现,下面这张图中的变量是用#符号开头,那么这个符号为啥可以阻止SQL的注入呢?

因为#{}会先将SQL语句预编译,为传入的参数设置占位符

${}参数传进来之后再编译SQL语句

而SQL注入发生在编译SQL语句阶段

这里用#符号做数据变量的开头就是声明了底层要用PreparedStatement,这是jdbc底层的一个接口,它的实例都是SQL语句,而这个接口会将它的实例进行预编译,然后再将数据通过setXXX方法传入SQL语句,然后运行。

简单来说#{}会将SQL语句预编译,坏人传入的SQL语句无法进行编译,就不会起作用。

相关文章

网友评论

    本文标题:浅谈SQL注入以Mybatis为例

    本文链接:https://www.haomeiwen.com/subject/pijuxqtx.html