该漏洞是在Redis客户端开源库redis-py中发现的,以下是该漏洞的工作原理:
OpenAI使用 Redis 将用户信息缓存到服务器上,这样就不需要为每个请求查询数据库。
使用 Redis Cluster 来分发这个负载到多个 Redis 实例上。
使用 redis-py 库来在Python 服务器上与 Redis 进行接口交互,该服务器使用 Asyncio 运行。
该库在服务器和集群之间维护共享连接池,并在完成后将连接回收以供另一个请求使用。
使用 Asyncio 时,redis-py 的请求和响应行为就像是两个队列:调用者将请求推入传入队列,然后从传出队列中弹出响应,然后将连接返回到池中。
如果在将请求推入传入队列之后,但在从传出队列中弹出响应之前取消了请求,我们就会遇到错误:连接因此变得损坏,为非关联请求接收到遗留在连接中的数据的下一个响应。
在大多数情况下,这会导致无法恢复的服务器错误,用户必须再次尝试其请求。
但在某些情况下,损坏的数据恰好与请求者所期望的数据类型相匹配,因此返回缓存的内容似乎有效,即使它属于另一个用户。
在太平洋时间 3 月 20 日星期一凌晨 1 点,OpenAI公司无意中对服务器进行了更改,导致 Redis 请求取消激增。这为每个连接返回错误数据创造了一定的概率。
此错误仅在 Asyncio redis-py 客户端对 Redis Cluster 中出现,现已得到修复。
对基础 bug 进行了广泛的测试。
添加了冗余检查,以确保 Redis 缓存返回的数据与请求用户匹配。
通过程序化地检查日志,确保所有消息仅对正确的用户可用。
相关多个数据源,精确定位受影响的用户,以便通知他们。
改进日志记录,以确定何时发生此问题,并完全确认已停止。
提高 Redis 集群的鲁棒性和扩展性,以减少极端负载下的连接错误发生的可能性。