赞
踩
很多人都知道SQL存在SQL注入引起的安全问题,但是很少有开发者去尝试过是怎样一个注入,下面将复现Mybatis的SQL注入问题并给出正确操作。
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for test -- ---------------------------- DROP TABLE IF EXISTS `test`; CREATE TABLE `test` ( `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `age` int(10) UNSIGNED NULL DEFAULT NULL, `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `age`(`age`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of test -- ---------------------------- INSERT INTO `test` VALUES (1, 25, 'Robert'); SET FOREIGN_KEY_CHECKS = 1;
select *
from test
where name like '%Ro%'
查询结果:
Robert';DROP TABLE test;--
这样SQL就变成:
select *
from test
where name like '%Robert';DROP TABLE test;--%'
执行后会发现我们的表被删掉了。这就是SQL注入漏洞。
我们Mybatis中动态SQL有${}和#{}两种解释方式:
如下使用${}:危险SQL
select *
from test
where name like '%${name}%'
使用#{}:安全SQL
select *
from test
where name like concat('%', #{name}, '%')
所以日常开发过程,一定要首选#{}方式,不得已情况下再使用${};
比如如下场景:test表有很多临时表,这些临时表表名是随机生成的,我们不能将表名直接写死到SQL,所以需要使用动态参数,如下:
select *
from #{table_name}
where name like concat('%', #{name}, '%')
这种情况使用#{}方式就会报错,因为table_name会被解析成字符串如下:
select *
from 'test'
where name like concat('%', 'Ro', '%')
在执行SQL时就报错,语法错误
改为${}就可以了,那么这时候还存在SQL注入隐患吗?试一下:
select *
from test;DROP TABLE test;--
where name like concat('%', 'Ro', '%')
发现test表仍被删除掉了,所以只要使用了${}就存在SQL注入隐患。
解决办法:对使用${}的动态参数在Java端做好严格管控:
以上就是关于SQL注入隐患的解释及解决方案,作为后端开发人员要时刻保持安全意识,永远记住一点:对外开放的接口都不是绝对安全。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。