原文链接:《Redis Lua scripting: several security vulnerabilities fixed》
作者:antirez
译者:Roy@Knownsec
一个多月前我收到一封来自 Apple 信息安全团队的邮件。他们在一次审计中发现了一个 Redis Lua 子系统中的安全问题,具体来说是在 cmsgpack 库中。这个库并非 Lua 的一部分,而是我自己按 MessagePack 实现的。在一次合并一个功能改进的 pull request 时引入了安全问题。后来他们又发现了 Lua struct 库的一个新问题,同样这个库也不是 Lua 的,至少不是我们用的这版 Lua 的:我们才刚把源码嵌入到自己的 Lua 实现里,以便能给 Redis 用户使用的 Lua 解释器添加一些功能。然后我就发现了该 struct 库的另一个问题,接着 Alibaba 团队也发现了许多 cmsgpack 的其他问题,并定位了调用这些 Lua API 的代码。我迅速地就被一堆 Lua 相关的漏洞淹没了。
这些漏洞更多地是影响在云端提供托管 Redis 服务器这一特定场景,毕竟没有 Redis 服务器权限的话,要利用已发现的漏洞几乎不可能:很多 Redis 用户根本就用不到 cmsgpack 或 struct 库,即使用也不大可能用在不可信的输入上。但云服务提供商就不同了:他们的 Redis 实例(通常有多种租约)是开放给了订阅服务的用户的。他或她可以发送任何东西给这些 Redis 实例,触发漏洞、破坏内存、影响甚至完全操控 Redis 进程。
比如这个 Python 小程序就能击溃 Redis,利用了 cmsgpack 其中一个漏洞。
https://gist.github.com/antirez/82445fcbea6d9b19f97014cc6cc79f8a
不过站在能控制 Redis 实例的输入的普通用户的角度来看,风险仅限于将不可信的内容传入诸如 struct.unpack()
的函数,还得首先刚好选到一种危险的解码格式 bc0
作为格式参数。
多亏了 Apple 信息安全团队、我,和 Redis 云服务提供商之间的积极配合和友好交流,我先联系上了所有重要的 Redis 提供商,尽量协调漏洞的发布,好让他们能先一步打上补丁。我提供了一个独立补丁,使得提供商能轻易应用到他们的系统中。最后从昨天到今天我准备了 Redis 3、4 和 5 的新的修复版本,修复了安全性。你在看这篇博文时这些都已经发布了。
不幸的是我没能联系上较小或较新的云服务提供商。处理与 Redis Lab, Amazon, Alibaba, Microsoft, Google, Heroku, Open Redis 和 Redis Green 的沟通已是竭尽全力,何况将信息扩散给其它主体将增加泄密的风险(各家公司都有很多人参与其中)。如果你是一名 Redis 服务提供商却今天才知道这个漏洞,我很抱歉,我已经尽力了。
感谢 Apple 信息安全团队以及其他提供商在这个问题上的提点与帮助。
老实说设计 Redis 的 Lua 引擎时,我并没设想过这种顾客与云服务提供商相对立的安全模型。这多少假设了 Redis 服务器的使用者是可信的。所以 Lua 库普遍没有经过安全审查。当时觉得你要是都有 Redis API 的权限了,你怎么都能干得比这更不安全。
不过后来事情就变了,云服务提供商限制了开放给顾客的 Redis API,以使提供托管的 Redis 实例成为可能。但拒绝了 CONFIG 或 DEBUG 这类命令,就不可避免地要开放 EVAL 和 EVALSHA(译者注:两个都是用来执行 Lua 脚本的命令)。Redis Lua 脚本是社区里最常用到的功能之一。
因此在我真正留意到之前,Lua 库也已因 Redis 开放给最终用户的方式发生变化而日渐成为本该由 Redis 处理的安全模型中的一个攻击点。如前所述,在这模型中相比 Redis 用户,是托管 Redis “云”服务提供商受影响更多,但无论如何这是个必须解决的问题。
我们能做些什么来改进云服务提供商目前在安全方面的状态,并兼顾 Lua 脚本的具体问题呢?我列出了一些事情,想在接下来的几个月去做。
修复问题的提交如下:
ce17f76b 安全性: 修复 redis-cli 缓冲溢出。
e89086e0 安全性: 修复 Lua struct 库偏移量处理。
5ccb6f7a 安全性: 更多 cmsgpack 的修复,来自 @soloestoy。
1eb08bcd 安全性: 更新 Lua struct 库,提升安全性。
52a00201 安全性: 修复 Lua cmsgpack 库栈溢出。
第一个提交与此无关,是一个 redis-cli 的缓冲溢出,只有在命令行中传入一个很长的主机参数时才会被利用。其它的才是我们发现的 cmsgpack 与 struct 库的问题。
这是两个复现问题的脚本:
https://gist.github.com/antirez/82445fcbea6d9b19f97014cc6cc79f8a
https://gist.github.com/antirez/bca0ad7a9c60c72e9600c7f720e9d035
两个都是苹果信息安全团队写的。但第一个我做了修改,以便能更稳定地复现。
几乎所有带 Lua 脚本的 Redis 都受到了影响。
修复的版本为以下 github tag:
3.2.12
4.0.10
5.0-rc2
稳定版(4.0.10)仍可在 http://download.redis.io 找到。
各发行版 tarball 文件的哈希值在此:
https://github.com/antirez/redis-hashes
请注意发行的版本中也包含了其他的修复,所以最好也读下版本说明,好了解切换到新版时其他会升级的东西。
希望再发博客时能带来为 Redis 的 Lua 脚本子系统规划的安全审计的报告。