是否可以将凭证传递给客户端以允许其将文件上传到 Amazon S3?

信息安全 证书 aws 云储存 亚马逊-s3
2021-09-05 04:30:29

我们的移动应用程序会将图像上传到 AWS S3。问题是是否执行以下选项之一:

  1. 将图像上传到我们的 API 服务器,然后我们的 API 服务器将图像上传到 S3
    Pros:更安全,因为 S3 凭据仅存储在云中。
    缺点: API 服务器的压力更大,因为成千上万的用户将上传图片,大小从 2 MB 到 10 MB 不等

  2. 通过从 API 服务器获取每个 S3 访问的临时 S3 凭据,让移动应用程序将图像直接上传到 S3。
    优点: API服务器压力较小,不会上传文件到服务器。
    缺点:安全性较低,因为 S3 凭据将暴露给移动设备,不管事实如何,移动应用程序每次访问 S3 时都会要求临时凭据,并且它通过与 API 服务器的 SSL 连接获取凭据。

那么,上面的选项二是否更好?因为我们已经授予临时凭证,每次只有 15 分钟有效,以便通过 SSL 连接访问 S3。

推荐的方法是什么?

3个回答

首选的方法是生成一个预签名的 POST 请求(您的后端服务器使用您自己的管理员凭据来请求它)。

然后从客户端使用这个预签名的 POST 上传。

这实际上是一种获得临时凭据的方法,但部署起来更加容易和安全,因为它可以限制为您需要上传的确切文件。

如果您使用 Ruby SDK ( https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/PresignedPost.html ),这里是链接,您会很容易找到 SDK你用。

编辑:根据评论,链接到官方 AWS 文档:https ://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html

我不确定是否有推荐的做法,但我认为它与应用程序的要求和平衡利弊有关。

会不会是服务器负载低?好的,我们可以使用服务器与 S3 一起工作,这显然是首选方法(并且它还保持与您的应用程序服务的其余部分相同的 API 上的交互)。

服务器的负载会不会太重?好的,替代方案是扩展服务器资源,或者看看让应用程序直接与 S3 一起工作的风险是否可以接受。

信息是否敏感?如果应用程序直接与 S3 通信,我们可以合理地保护它吗?如果它不是高度敏感的并且可以得到合理的保护并且风险小于扩展服务器以处理负载的成本,那么这可能是您的选择。

这些信息是高度敏感的,如果 S3 密钥从 SSL 或设备中被嗅出,会发生可怕的事情吗?在这种情况下,将钱花在扩展服务器架构上可能是值得的。

我不认为有任何一种推荐的方式......自然只从你的服务器处理 S3 更安全(你在安全论坛上问这个问题,所以我认为这是你的主要关注点),但总而言之它变成了由应用程序的需求驱动的平衡。

实现它的一个好方法是生成只能上传到特定存储桶部分(用户有权访问的部分)的临时凭证。

即使这些凭据从内存中被盗(我假设您在每次通信中都使用 https,因此它们在传输过程中不会被盗),最终用户也只能将它们用于预期用途:上传文件。

此处提供了一个示例

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":"s3:PutObject",
         "Resource":"arn:aws:s3:::my_corporate_bucket/uploads/widgetco/*"
      },
      {
         "Effect":"Deny",
         "NotAction":"s3:PutObject",
         "Resource":"arn:aws:s3:::my_corporate_bucket/uploads/widgetco/*"
      },
      {
         "Effect":"Deny",
         "Action":"s3:*",
         "NotResource":"arn:aws:s3:::my_corporate_bucket/uploads/widgetco/*"
      }
   ]
}

我建议您还通过验证允许的扩展名/文件签名定期检查存储桶中的所有文件(小心,这可能会变得非常耗时)。您还可以根据文件扩展名更多地限制您的策略(来源此处

{
  "Id": "Policy1464968545158",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1464968483619",
      "Action": [
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::<yourbucket>/*.jpg",
      "Principal": "*"
    },
    {
      "Sid": "Stmt1464968543787",
      "Action": [
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::<yourbucket>/*.png",
      "Principal": "*"
    }
  ]
}