在 AWS Lambda 上执行任意代码

在 AWS Lambda 上执行任意代码

我正在开发一款 SaaS,用户可以上传自定义 JavaScript 函数,该函数在事件发生时运行。为了保持系统的完整性,我使用 AWS Lambda 来运行这些函数,这样它们就可以独立于系统的其他部分运行。

一般情况下,付费客户会分配到他们自己的 lambda,他们可以通过我的 web 界面将代码部署到其中。他们有责任确保代码的安全,因为他们为此付费。

不过,我还想提供一个演示选项,以便新客户可以上传一些自定义代码,并在取出钱包之前查看系统如何工作。因此问题如下:

假设 AWS Lambda 具有最低限度的 IAM 权限(它甚至无法生成 CloudWatch 日志)。它链接到 API 网关,因此每当请求某个 URL 时都会调用它,例如POST /demo。潜在用户可以将任意 JavaScript 代码 POST 到 Lambda(假设是 Node.js v12 运行时),然后它会eval返回结果。另一个用户可以在他们之后 POST 任意代码,依此类推。

这个计划听起来可行,但后来我读到了AWS Lambda 白皮书并发现有时执行环境在调用之间被重复使用。这意味着恶意用户可以写入一个文件,而/tmp其他用户稍后可以读取该文件。坦率地说,我不在乎是否/tmp是唯一可写的目录。但我担心的是,用户是否可以覆盖源代码本身,用index.js他们自己的恶意版本替换我的。我假设,由于白皮书明确指出是/tmp可写的,文件系统的其余部分是只读的。这意味着攻击者无法修改我的源代码并劫持该函数。事实上,我刚刚通过以下方式尝试过LambdaShell,并收到以下错误:

Command failed: printf hello > index.js
/bin/sh: index.js: Read-only file system

一切都很好!

因此,ServerFault,我还有以下问题:

  1. 演示 Lambda 是否应允许 Internet 访问?虽然攻击者可以检索我的 AWS 凭证,但如果函数角色在 IAM 中正确锁定,这些凭证基本上就毫无用处了。可以通过为演示 Lambda 使用一个极小的超时期限来停止无限循环或大量下载。

  2. 我在开头提到,每个付费客户都会获得自己的 lambda。这是基于我的假设,因为运行时在执行之间共享,所以实际上没有办法将客户代码彼此隔离(此外,如果客户保存到/tmp,下一个客户可能会搞乱它)。

但是,让我们假设客户不关心或不使用。使用相同的 Lambda 为每个客户/tmp动态加载和编码是否安全?eval

假设客户代码托管在 S3 中customerA.js,例如customerB.js、 等。当事件发生时,我的代码会以某种方式确定应运行的代码的文件名。Lambda 将从 S3 下载此代码,eval然后返回结果。

因此,攻击者能够从 S3 请求文件名并读取它,但我们可以限制他们列出文件或在 S3 上执行任何其他操作的能力。但这还不够,因为客户 A 可以customerB.js通过他们的恶意代码请求并窃取它。

为了增加难度,我们假设可以通过 webhook 触发事件,这样有人就可以继续/trigger/customerA/with/params触发客户 A 的 Lambda。这样我们就无法随机化文件名,让它们更难猜测,因为我们必须能够根据请求的 URL 确定文件名。

我不是 IAM 专家,但是否可以构建一个基于 API 网关请求 URL 限制 S3 访问的策略?例如,告诉 AWS 触发的 Lambda/trigger/customerA/*只能读取 S3 文件customerA.js,而不能读取其他文件。这将阻止攻击者在基础设施级别读取其他客户的代码,并且不需要我提供任何额外的代码。

我认为这种方法是错误的,但我对其他人的看法很感兴趣。允许客户共享 lambda 将使我能够取消入职费,这只是为了防止新用户在我的 AWS 账户上创建新的 lambda,直到他们提供付款方式(部分原因是 Lambda 数量有限制,部分原因是我不想让新用户在我承担责任之前把我的账单搞得一团糟)。

谢谢大家的意见!

相关内容