如何在Redis缓存穿透场景下联防后端的SQL注入风险

云墨同学_8943

云墨同学_8943

2026-10-01

711人浏览

原创

缓存穿透与sql注入可协同攻击,空值缓存无法防御sql注入,因其不校验key合法性;必须在请求入口层对参数做正则校验、类型转换和范围检查,从源头拦截非法输入。

如何在redis缓存穿透场景下联防后端的sql注入风险

缓存穿透和SQL注入不是两个孤立问题,而是一对协同攻击组合:恶意构造的无效key往往伴随非法字符,不拦截就可能进数据库触发注入。

为什么空值缓存本身挡不住SQL注入

很多人以为加了 redis.setex(key, 60, "") 就万事大吉,但这是错觉。空值缓存只解决“查不到数据要不要缓存”的问题,它完全不校验 key 本身是否合法。比如传入 user:1'; DROP TABLE users; -- 这种字符串,Redis照单全收,空值缓存也照设不误——可一旦后续某个分支绕过缓存(比如管理后台直连DB),或空值过期后重查,这个恶意 payload 就直接进了 SQL 查询语句。

常见疏漏点:

  • 只在缓存层做空值写入,没在参数进入 DAO 前做白名单/格式校验
  • 把 userId 当作纯数字处理,但实际接收的是字符串,未做 Integer.parseInt() 或正则过滤
  • 用 MyBatis 的 ${} 拼接 ID,而非 #{} 预编译

必须在缓存入口处做参数合法性校验

真正有效的联防,是把校验卡在最外层:请求刚进来、还没碰 Redis 时就拒绝非法输入。这不是“多此一举”,而是让穿透请求根本没机会生成 key。

实操建议:

  • 对所有用于拼接 Redis key 的字段(如 userId、orderId),强制走正则校验:^[a-zA-Z0-9_\-]{1,32}$ —— 拒绝任何含空格、引号、分号、括号的输入
  • 数字型 ID 必须先转整型再校验范围:Long.parseLong(id) > 0 && id ,防止负数或超长数绕过
  • 若使用 Spring Boot,推荐用 @Pattern + @Min 注解统一约束 DTO,避免每个 service 方法重复写 if
  • 校验失败直接返回 HTTP 400,不记录日志(防探测)、不进 Redis、不查 DB

布隆过滤器不能替代参数校验

布隆过滤器(RBloomFilter.contains(key))确实能高效拦截大量不存在的 key,但它本质是概率型结构:存在误判率(哪怕 0.01%),且无法识别字符串内容是否含恶意字符。一个被布隆过滤器“放行”的 user:123;--,仍会落到 DAO 层执行 SELECT * FROM users WHERE id = '123;--'。

Redis Skill - 高性能缓存管理
Redis Skill - 高性能缓存管理

Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。

下载

所以正确顺序只能是:

  • 第一步:参数格式校验(阻断非法字符)
  • 第二步:布隆过滤器判断 key 是否可能有效(减少无效 DB 查询)
  • 第三步:查 Redis → 查 DB → 写空值(仅对已通过前两步的请求)

三者缺一不可,且顺序不可颠倒。

警惕 ORM 框架里的“自动逃逸”幻觉

有人觉得用了 JPA/Hibernate/MyBatis 就天然防注入,这是危险认知。这些框架只对 #{}、:param 这类占位符语法做预编译逃逸,但如果你写了 @Query("SELECT * FROM user WHERE id = '" + userId + "'") 或 MyBatis 的 ${id},那框架完全不干预,恶意字符串原样进 SQL。

关键检查点:

  • 全局搜索项目中所有 ${}、+ 字符串拼接、String.format 构造 SQL 的地方
  • DAO 方法签名里,ID 类型尽量用 Long 而非 String,从类型层面堵住字符串注入入口
  • 测试阶段用 ' OR '1'='1 这类 payload 手动发请求,验证是否真被拦截(而不是返回空或 500)

最易被忽略的一点:缓存穿透防御代码里写的 redis.setex(key, 30, ""),那个 key 变量如果未经清洗就直接拼进 Redis 命令,本身也可能触发 Redis 协议注入(虽然罕见,但在某些客户端实现下存在风险)。所以 key 的合法性校验,必须发生在任何缓存操作之前,且独立于缓存逻辑本身。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

redis sql注入 redis缓存

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2203

5

前端和后端的区别
前端和后端的区别

前端关注的是用户界面的设计和交互,而后端则注重数据处理和逻辑控制。想了解更多前端后端的相关内容,可以阅读本专题下面的文章。

2024.03.19

5830

13

后端的主要工作内容介绍
后端的主要工作内容介绍

后端是应用程序的服务端部分,负责核心任务,如数据库交互、业务逻辑处理和响应客户端请求。想了解更多后端的相关内容,可以阅读本专题下面的文章。

2024.03.19

5146

10

数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

3903

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

831

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1009

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5721

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2683

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5700

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpEnv手册
phpEnv手册

共0课时 | 0人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.5万人学习