Web项目SQL 注入与防御
一、概念
SQL注入,一般指web应用程序对用户输入数据的合法性没有校验或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
总的来说就是,攻击者通过系统正常的输入数据的功能,输入恶意数据,而系统又未作任何的校验,直接信任了用户输入,使得恶意输入改变原本的SQL逻辑或者执行了额外的SQL脚本达,从而造成了SQL注入攻击。
二、SQL注入场景
' or '1'= '1,这是最常见的 sql 注入攻击,当我们输如用户名 xiaobaicai ,然后密码输如'or '1'= '1的时候,我们在查询用户名和密码是否正确的时候,本来要执行的是select * from user where username='' and password='',经过参数拼接后,会执行 sql 语句select * from user where username='xiaobaicai' and password=' ' or ' 1'='1 ',这个时候 1=1 是成立,自然就跳过验证了。
但是如果再严重一点,密码输如的是';drop table user;--,那么 sql 命令为select * from user where username='xiaobaicai' and password='';drop table user;--' 这个时候我们就直接把这个表给删除了
三、防御
1. 在 java 中,我们可以使用预编译语句(PreparedStatement),这样的话即使我们使用 sql 语句伪造成参数,到了服务端的时候,这个伪造 sql 语句的参数也只是简单的字符,并不能起到攻击的作用。
2. 合理规范使用持久层框架。比如,MyBatis 框架中,${}是输出变量的值,相当于拼接SQL,而#{}则是用了jdbc中的preparedstatement预编译。所以我们在日常开发中,用#{}就可以有效避免SQL注入,而只要是用了${}都有被注入的可能。不过,在MyBatis开发过程中注意以下几点:
某些xml自动生成工具生成的xml,动态条件用了${};在开发过程中需注意,特别是多表查询时;
进行like查询,使用
select * from xiaobaicai where tile like concat(‘%’,#{title}, ‘%’);
包含in语句的时候,使用
<foreach collection="ids" item="item" open="("separatosr="," close=")">
</foreach>
使用order by语句的时候,用
3. 数据库中密码等重要信息不应明文存储的,可以对密码进行加密(比如,MD5+盐值(随机字符长+多次散列算法)数据库存储用户名等加密后的密文存贮。
--------------------------------------