0%

SQL注入攻击防御

SQL注入攻击防御

什么是SQL注入

所谓SQL注入,就是通过把SQL命令伪装成正常的HTTP请求参数,传递到服务端,欺骗服务器最终执行恶意的SQL命令,达到入侵目的。攻击者可以利用SQL注入漏洞,查询非授权信息,修改数据库服务器的数据,改变表结构,甚至是获取服务器root权限。总而言之,SQL注入漏洞的危害极大,攻击者采用的SQL指令,决定攻击的威力。当前涉及到大批量数据泄露的攻击事件,大部分都是通过利用SQL注入来实施的。

当用户输入nick为zhangsan,密码为**’ or ‘1’=’1**的时候,会导致用户登录成功

如何进行防御

  1. 使用预编译语句
    预编译语句PreparedStatement是java.sql中的一个接口,继承自Statement接口。通过Statement对象执行SQL语句时,需要将SQL语句发送给DBMS,由DBMS先进行编译后再执行。而预编译语句和Statement不同,在创建PreparedStatement对象时就指定了SQL语句,该语句立即发送给DBMS进行编译,当该编译语句需要被执行时,DBMS直接运行编译后的SQL语句,而不需要像其他SQL语句那样首先将其编译。

前面说SQL注入攻击时,引发SQL注入的根本原因是恶意用户将SQL指令伪装成参数传递到后端数据库执行,作为一种更为安全的动态字符串的构建方法,预编译语句使用参数占位符来替代需要动态传入的参数,这样攻击者无法改变SQL语句的结构,SQL语句的语义不会发生改变,即便用户传入类似于前面**’ or ‘1’=’1**这样的字符串,数据库也会将其作为普通的字符串来处理

  1. 使用ORM框架
    由上文可见,防止SQL注入的关键在于对一些关键字符进行转义,而常见的一些ORM框架,如mybatis、hibernate等,都支持对相应的关键字或者特殊符号进行转义,可以通过简单的配置,
    很好的预防SQL注入漏洞,降低了普通的开发人员进行安全编程的门槛。

mybatis的insert语句配置:

1
2
3
4
5
<insert id="insert" parameterClass="user">
insert into
users(userid,user_nick,address,age,sex)
values(#{userId},#{userNick},#{address},#{age},#{sex})
</insert>

通过#{}符号配置的变量,mybatis能够对输入变量的一些关键字进行转义,防止SQL注入攻击

3.避免密码明文存放
对存储的密码进行单向Hash,如使用MD5对密码进行摘要,而非直接存储明文密码,这样的好处就是万一用户信息泄露,即圈内所说的被“拖库”,黑客无法直接获取用户密码,而只能得到一串跟密码相差十万八千里的Hash码。

4.处理好相应的异常
后台的系统异常,很可能包含了一些如服务器版本、数据库版本、编程语言等等的信息,甚至是数据库连接的地址及用户名密码,攻击者可以按图索骥,找到对应版本的服务器漏洞或者数据库漏洞进行攻击,因此,必须要处理好后台的系统异常,重定向到相应的错误处理页面,而不是任由其直接输出到页面上