SQL 注入就是通过把 SQL 命令插入到 Web 表单提交或输入域名或页面请求的查询字符串,服务器拿到这个字符串之后,会把这个字符串作为 sql 的执行参数去数据库查询,然而这个参数是恶意的,以至于服务器执行这条 sql 命令之后,出现了问题。

下面直接弄个案例吧,这样容易理解一些。

比如,在一个登录界面,要求输入用户名和密码,可以这样输入实现免帐号登录:

用户名: ‘or 1 = 1 --
密 码:

用户一旦点击登录,如若没有做特殊处理,那么这个非法用户就很得意的登陆进去了。

这是为什么呢?

下面我们分析一下:从理论上说,后台认证程序中可能会有如下的SQL语句:

String sql = “select * from user_table where username=’ “+userName+” ’ and password=’ “+password+” ‘”;

注:可以左右拉动,下同

因此,当输入了上面的用户名和密码,把参数代进去,则上面的SQL语句变成:

SELECT * FROM user_table WHERE username=’’or 1 = 1 –- and password=’’

分析上述SQL语句我们知道,username=‘ or 1=1 这个语句一定会成功;然后后面加两个-,在 sql 中,两个 -这意味着注释,它将后面的语句注释,让他们不起作用。这样,后面的and password=’’语句将不会执行,所以上述语句永远都能正确执行,用户轻易骗过系统,获取合法身份。

应对方法

(1). 参数绑定

使用预编译手段,绑定参数是最好的防SQL注入的方法。目前许多的 ORM 框架及 JDBC 等都实现了 SQL 预编译和参数绑定功能,攻击者的恶意SQL会被当做SQL 的参数而不是 SQL 命令被执行。

在mybatis的mapper文件中,对于传递的参数我们一般是使用 # 和$来获取参数值。

当使用#时,变量是占位符,就是一般我们使用 javajdbc 的 PrepareStatement 时的占位符,所有可以防止 sql 注入;当使用 $时,变量就是直接追加在sql中,一般会有 sql 注入问题。

(2). 使用正则表达式过滤传入的参数,例如把出现双-的过滤掉等等。