什么是SQL注入

在程序中,经常需要动态构建一些SQL语句传递给数据库执行,攻击者通过向这些动态SQL中传入一些特殊字符,从而可以改变原有SQL的语义,甚至注入自定义的SQL语句,这种攻击手段称为SQL注入攻击。
例如,程序中的一个验证登录的查询语句如下:

  1. "select * from users u where u.userid='"+userid+"' and u.passwrod='"+password+"'";

其中useridpassword是通过前端页面传递过来的,如果攻击者将其中的password传入如下字符:' or '1'='1,这条sql语句就变成了如下样子,从而轻松绕过登录密码的限制:

  1. "select * from users u where u.userid='"+userid+"' and u.passwrod='' or '1'='1'";

有什么危害

SQL注入漏洞可以改变SQL查询的语义,甚至将数据库完全暴露出来,表结构、业务数据全部一览无余。

预防思路

从上文可以看到,SQL注入漏洞的核心在于动态拼接的SQL,因此预防思路很容易可以想到:不采用动态拼接SQL,或者对动态SQL的输入参数进行严格校验、对特殊字符进行处理。

具体措施

SQL注入一般存在于表单提交、搜索框查询等需要后台执行SQL查询的地方,这些场景需要经过如下几个步骤:前台输入,后台Controller层接收转发,业务逻辑层执行查询并通过Controller层返回。下面依次从这几个步骤进行分析:

1、前台输入校验

前台对输入的内容需要根据业务逻辑进行校验,包括非空校验、数据类型、长度、取值范围、格式几个方面。

2、Controller层校验

前台页面的限制对攻击者来说形同虚设,很容易就可以破解,例如修改HTML、模拟HTTP请求等。因此前台侧重点在输入内容业务逻辑合法性方面的校验,真正的安全性校验还需要在Controller层进行。
这部分校验除了要执行上述数据的类型、长度等方面的校验外,还需要特别关注cookie(是否存在、是否合法等)、Response中的HTML标签字符(这些是 HTML 敏感字符:< > " ' % ; ) ( & + )。

3、业务逻辑层校验

这部分核心在于对特殊字符的过滤,对动态拼接的SQL语句可以采用PreparedStatement方式将输入内容参数化,自动对特殊字符进行转码。另外一些ORMapping框架封装,通过操作实体Bean来操作数据库,这种方式框架会自动生成SQL语句,并对特殊字符进行了处理。

参考XMind图

SQL注入.xmind