Knative冷启动劫持
摘要 Knative 通过保留最小数量的常驻 Pod 来加速无服务器函数的冷启动,但其容器复用策略在安全性与性能之间制造了一道危险的裂缝:当某个函数容器被重用时,其内存中可能残留上一个请求的变量、环境密钥、数据库连接池或临时文件。攻击者可以在 Serverless 平台上发起一个合法请求,利用容器复用时未清理的 tmpfs 或环境变量读取上一个租户的残留数据。部分平台为了降低延迟,甚至不重启 Node.js 或 Python 进程,仅清空 HTTP 上下文,使得跨请求的数据残留成为系统性缺陷。 Knative 冷启动优化与实例复用 冷启动的代价与优化 Knative Serving 基于 Kubernetes,为每个函数实例(Revision)创建 Pod 来服务请求。当函数长时间未收到请求时,Knative 会将其 Pod 缩减到零以节省资源。下一个请求到达时,需要重新创建 Pod、拉取镜像、启动容器、初始化运行时环境——这一“冷启动”过程可能耗费数秒,远高于用户体验可接受的延迟。 为了降低冷启动延迟,Knative 引入了 容器实例保持 策略:即使没有活跃请求,也保留一个或多个“温暖”的 Pod 在内存中等待。 当新请求到达时,这些温暖的 Pod 可以立即处理请求,避免镜像拉取和运行时初始化。这些温暖的 Pod 可能被同一个函数实例的多个请求复用,甚至在某些配置下被同一命名空间内的不同函数实例复用。 实例复用时的内存语义 当一个温暖的 Pod 被复用时,Knative 不会重新启动容器进程,而是直接向现有进程发送新的 HTTP 请求。对于 Node.js、Python 等解释型语言运行时,这意味着同一进程的内存空间将被多个请求共享。tmpfs、环境变量、全局变量和堆中的对象都保持原样,只有 HTTP 上下文被重新初始化。 这种“进程级复用”带来了显著的安全隐患:如果前一个请求在内存中留下了敏感数据,这些数据可能被后续请求读取。例如: 用户 A 提交了一个包含 API 密钥的函数请求,该密钥被存储在某个全局变量或 tmpfs 文件中。 用户 B 随后向同一函数实例发起请求,如果用户…