如何编写单元测试验证 SQL 注入防护
时间:2026-08-23 | 作者:清风无痕 | 阅读:0要想测试真正有效,就必须让恶意输入穿透校验层、拼接逻辑以及DAO调用,从而触发业务层异常(比如IllegalArgumentException),而不能仅仅验证不报错。而且,还需要覆盖${}拼接、二次注入等高危路径,并对审计日志进行检查。
测试必须传真实恶意字符串,不能 mock DAO 返回值
不少测试之所以失败,并非防护措施没做好,而是测试过程中绕过了关键路径。比如说,在service层对userRepository.findByUsername的返回值进行了mock,然而却并未将"admin'--"真正传入方法体,这无异于测试了一个虚假的流程。
真正有效的测试要让输入穿透校验层、拼接逻辑(如果有)、DAO 调用,直到触发异常或安全执行。否则你测的不是“防护是否生效”,而是“mock 是否配对成功”。
- 用
userService.findByUsername("admin'--")调用,而不是when(userRepository.findByUsername(any())).thenReturn(...) - 如果底层是 MyBatis,确保测试走的是
select * from users where name = #{name}路径,而非${name}拼接分支 - 对 JSON 接口,测试 body 原始内容含
%27(URL 编码单引号),确认解码后仍被拦截
断言目标不是“不报错”,而是“抛指定业务异常”
看到测试通过就以为安全?错。很多框架默认允许单引号,仅靠数据库驱动语法校验不可靠——MySQL 可能直接报 MySQLSyntaxErrorException,PostgreSQL 却可能静默截断或返回空结果。
真正要验证的是:防护逻辑是否在 DB 执行前就拦截了。所以 assert 必须明确指向业务层异常,比如 IllegalArgumentException 或自定义的 InvalidInputException。
- 正确:
assertThatThrownBy(() -> service.login("root' OR '1'='1"))+.isInstanceOf(IllegalArgumentException.class) - 错误:
assertThatCode(() -> service.login("...")).doesNotThrowAnyException()—— 这只说明没崩,不代表没进 DB - 若实际抛出
PSQLException或SQLServerException,说明防护失效,请求已抵达数据库
覆盖 ${} 和字符串拼接等危险写法
MyBatis 的 ${}、JPA 的 createNativeQuery、Ja va 的 String.format 或 + 拼接,都是高危点。单元测试必须显式构造这些分支并验证其行为。
尤其注意旧代码里藏得深的拼接逻辑:比如先从 DB 查出模板 SQL,再用用户输入填充字段名或表名——这种场景 #{} 也救不了你。
- 对使用
${tableName}的 mapper,传入"users; DROP TABLE admins--",验证是否抛出预期异常 - 对
String sql = "SELECT * FROM " + userInput;这类代码,测试需触发运行时异常(如SQLException)或记录非法日志 - Hibernate 场景下,检查是否用了
@Param绑定,而非createNativeQuery("SELECT * FROM users WHERE name = '" + input + "'")
避免用 @Sql 或 H2 执行真实 SQL
用内存数据库跑一条带 ' OR 1=1 的查询,看它返回全表数据——这不是在测你的防护,是在测 H2 的 SQL 解析器是否够严。
真实防护逻辑发生在 Ja va 层:正则过滤、白名单校验、参数绑定调用。数据库只是最终执行者。把测试焦点放在 DB 层,等于把责任推给方言实现,而不同数据库对非法输入的响应差异极大。
- 禁用
@Sql(scripts = "malicious-data.sql")类测试,它无法验证你写的校验逻辑是否触发 - 不要依赖 H2/hsqldb 的“报错即拦截”行为——它们不模拟 MySQL 的注释解析、PostgreSQL 的类型强转
- 重点检查日志:当恶意输入进来时,是否记录了
"Blocked SQL injection attempt: ..."这类审计日志
最常被忽略的一点:二次注入。测试不能只盯着即时接口,还要覆盖“先存后查”路径——比如注册时存入 "admin'; --",登录时再查这个字段触发拼接。这种延迟执行的漏洞,单元测试里最容易漏掉。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- 迅捷路由器怎么调信号最强,设置时要注意什么?
- 时间:2026-08-27
-
- vivo浏览器怎么卸不掉?原因和解决方法在这里
- 时间:2026-08-27
-
- OPPO R11s黑屏了,怎么强制恢复出厂设置?
- 时间:2026-08-27
-
- 飞利浦显示器包装盒有生产日期和保修期吗?怎么看?
- 时间:2026-08-27
-
- 联想新平板开机必须联网吗?怎么做?
- 时间:2026-08-27
-
- 平板横竖屏切换设置与问题解决
- 时间:2026-08-27
-
- 移动电源容量怎么测?要准备哪些工具?
- 时间:2026-08-27
-
- 荣耀90 Pro防水吗?防水级别多少?怎么用才安全
- 时间:2026-08-27
精选合集
更多大家都在玩
大家都在看
更多-
- 糖尿病完全不能吃糖吗
- 时间:2026-09-15
-
- 蚂蚁庄园小课堂2026年9月16日最新题目答案
- 时间:2026-09-15
-
- 小鸡答题今天的答案是什么2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园每日答题答案2026年9月16日
- 时间:2026-09-15
-
- 以下哪种粮食是酿造绍兴黄酒的主要原料 蚂蚁庄园今日答案9月16日
- 时间:2026-09-15
-
- 劝学名句“及时当勉励,岁月不待人”出自哪位诗人 蚂蚁庄园今日答案9.16
- 时间:2026-09-15
-
- 蚂蚁庄园今天答题答案2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园答题今日答案2026年9月16日
- 时间:2026-09-15
