Apple 安全漏洞研究部门于 2018 年 5 月通知我们 Redis 中存在一个潜在可利用的错误。我们非常重视这一披露,并投入资源妥善修复此问题。我们很高兴地告诉您,开源 Redis 的创建者和首席开发者 Salvatore Sanfilippo 已经为开源用户提供了补丁,并联系了所有主要的 Redis 提供商。我们已将此修复推送到我们所有的 Redis Enterprise 产品:Cloud、VPC 和 Software。
背景:Redis 嵌入了 Lua 用于数据库级别的脚本编写。Lua 脚本引擎包含许多与 Redis 用例相关的库。最初发现的 bug 与 MsgPack 库有关,它是 MessagePack 序列化格式的一种实现。MessagePack 类似于 JSON,但更节省空间,因为它依赖二进制编码进行控制,并在可能的情况下对值本身进行编码。
Lua 提供了一个接受可变数量参数(variadic)的函数,用于使用 MessagePack 格式“打包”消息。此可变参数函数的实现没有正确检查堆栈可用性。如果没有此检查,可以将非常大量的参数传递给此函数,导致溢出。由于 Redis 的性质,来自不受信任用户的数据可能正以这种方式被接受和处理。
没有已知的此 bug 的“野外”利用。由于此 bug 的性质,与任何溢出情况一样,理论上可以通过它执行远程代码执行,但这必须针对非常特定的 Redis 版本在非常特定的场景下进行。我们尚未得知此行为的任何概念验证。更有可能的是,此 bug 可被利用来导致不稳定或 Redis 服务器崩溃。
在审查过程中,通常会审查代码库的其他部分以查找相关的错误。在此过程中,Salvatore 在 OSS 社区的协助下,在 Lua 对其他结构进行打包和解包的实现中发现了类似的 bug。我们已实施修复来解决这些问题。
Apple 安全漏洞研究部门还提出了关于 Sentinel 远程配置作为安全风险的问题。我们不同意此发现,因为 Redis 明确且清晰地启用了远程配置,前提是 Sentinel 不应通过面向公众的地址访问。
此外,Redis Enterprise 不使用 Sentinel 来实现高可用性,而是使用其他内部机制,因此此发现对 Redis Enterprise 用户没有影响。
2.8.18 版本之后所有未打补丁的 Redis 版本都可能受到影响。要处于风险之中,您必须同时使用 Lua 并直接允许不受限制的用户输入以非常特定的方式传递到脚本中。虽然我们认为以这种方式一起使用这些功能的用户比例非常小,但我们仍然建议所有人应用补丁,以防止未来在未打补丁的系统上出现攻击媒介。
该补丁增加了对堆栈可用性的正确检查,并在 Lua 脚本尝试打包过大的消息时返回错误。这确保了在运行时,这种特定的攻击将不可能发生。
我们已检查 Redis 的其他部分是否存在类似的 bug,并且到目前为止尚未发现具有相同风险级别的任何其他 bug。
通常,只要您使用我们的访问控制(Cloud Security Group)和认证(SSL、密码)/访问控制(SIP)机制之一,您的 Redis 就应该是安全的。此外,如果您的应用程序不使用 Lua 脚本,您应该不会遇到任何问题。即使您的应用程序使用 Lua,此 bug 也会在极端条件下发生,并且只有当您的应用程序使用非常大量的参数调用 Lua 时才会发生。由于此 bug 自 Redis 支持 Lua 发布以来(2014 年)就已存在,我们认为您之前可能并未遇到此问题,并且除非您的应用程序发生巨大变化,否则此问题影响您 Redis 部署的可能性极低。此外,Redis Enterprise 内置了复制、自动故障转移和数据持久化机制,确保在 Redis 发生故障时您数据的高可用性和持久性。
如果您在本地部署中使用 Redis Enterprise 软件,可以从此处下载包含漏洞修复的最新 Redis Enterprise 版本。
最后但同样重要的是,确保您的 Redis Enterprise 数据库受到密码和访问控制及认证机制的保护。
我们建议开源用户首先确保任何 Redis 实例未不受限制地暴露在互联网上,然后升级到最新版本的 Redis(撰写本文时为 3.2.12、4.0.10 或 5.0-rc2),可在 redis.io 下载页面找到。