AWS Lambda函数似乎忽略了其指定的执行角色

时间:2018-01-13 01:38:16

标签: amazon-web-services amazon-s3 aws-lambda

我想做什么

对我拥有的特定Bucket进行Lambda函数访问(使用读取写入权限)。

只是那个Bucket,它不需要访问任何其他东西。

我做了什么

  1. 我设置了一个公共Bucket(实际上是正确的,我实际上希望任何人都可以访问它的内容),名为orca-resources
  2. 我创建了一个名为lamba-s3-orca-resources的IAM角色。它被设置为由Lambda服务使用。
  3. 我创建了一个最终由API Gateway
  4. 触发的Lambda函数
  5. 我编写了尽可能少的代码来尝试破坏我的政策:我访问了另一个我的那个,我的lamba-s3-orca-resources没有明确允许访问IAM角色
  6. 测试函数实际上会产生我希望不可用的Bucket的内容。此外,s3:listObjects即使在我的Allow动作中也是如此。

    我在俯瞰什么?

    Lambda函数

    其代码:

    'use strict';
    
    const aws = require('aws-sdk');
    const s3 = new aws.S3();
    
    exports.handler = (event, context, callback) => {
        s3.listObjects({Bucket: 'orca-exe'}, callback);
    };
    

    其执行角色:

    {
      "roleName": "lamba-s3-orca-resources",
      "policies": [
        {
          "document": {
            "Version": "2012-10-17",
            "Statement": [
              {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                  "s3:PutObject",
                  "s3:GetObject",
                  "s3:GetObjectTagging",
                  "s3:ListBucket",
                  "s3:DeleteObject"
                ],
                "Resource": [
                  "arn:aws:s3:::orca-resources/*",
                  "arn:aws:s3:::orca-resources"
                ]
              }
            ]
          },
          "name": "orca-resources-only",
          "type": "inline"
        }
      ]
    }
    

1 个答案:

答案 0 :(得分:4)

  

“AWS Lambda函数似乎忽略了其指定的执行角色”

从某种意义上说,这是真实的,并且是设计的,因为执行角色的细节不是Lambda服务或您的功能实际意识到的东西。 Lambda函数和Lambda基础结构实际上并未查看或了解与执行角色关联的权限。 Lambda并不负责执行此政策。

幕后会发生一些黑魔法,将所有这些拼接在一起,并了解其工作原理可能有助于解释为什么您所看到的行为是预期和正确的。

首先,Lambda执行角色是IAM角色。

  

问:什么是IAM角色?

     

IAM角色是一个IAM实体,它定义了一组用于发出AWS服务请求的permissions。 IAM角色与特定用户或组无关。相反,可信实体承担角色,例如IAM用户,应用程序或AWS服务,例如EC2。

     

- https://aws.amazon.com/iam/faqs/

当您担任角色时,您会发布一组临时凭证 - 一个访问密钥和密钥(类似于IAM用户凭据)以及一个传达相关权限的安全或会话令牌,所有这些都必须伴随这些凭据用于签名请求时。在Lambda函数中,这一切都是自动完成的。

调用Lambda函数时,Lambda服务本身会在会话令牌服务中调用AssumeRole

  

<强> AssumeRole

     

返回一组临时安全凭证(包括访问密钥ID,秘密访问密钥和安全令牌),您可以使用这些凭据访问通常无法访问的AWS资源。

     

- https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html

此操作(您的角色的信任策略允许)返回一组凭据,这些凭据作为环境变量放入Lambda容器的环境中,其名称为AWS_ACCESS_KEY_ID,{{ 1}}和AWS_SECRET_ACCESS_KEY(具体名称为dependent on the environment)。

AWS SDK随后automatically uses these environment variables签署您在Lambda函数中生成的所有请求。

Lambda中没有任何内容会针对角色策略筛选这些请求,原因有两个:与简单地允许目标服务的正常身份验证和授权机制进行身份验证相比,这将是一个更复杂且易于攻击的解决方案并且授权请求......但也许更重要的是,Lambda服务实际上无法通过AWS SDK告知您的代码正在尝试哪些操作,因为这些请求默认情况下通过HTTPS传输到服务端点,因此它不是&# 39;他们有可能接受检查。

您提出请求的服务随后对凭据进行身份验证,并在IAM和STS的帮助下授权请求 - 确定请求签名是否有效,随附的令牌是否有效以及是否针对允许指定的资源。

最后一点是你的假设模糊的地方。

处理请求的服务必须回答的问题有两个:

  • 请求的主体是否拥有来自其帐户的权限来发出请求,
  • 请求的主体是否拥有来自拥有资源的帐户的权限才能发出请求

这是两个问题,但是当主体(角色)和资源(存储桶)由同一个帐户拥有时,它们可以合并为一个问题,通过组合多个地方的结果来回答。

  

访问策略描述了谁有权访问什么。您可以将访问策略与资源(存储桶和对象)或用户相关联。因此,您可以按如下方式对可用的Amazon S3访问策略进行分类:

     

基于资源的策略 - 存储桶策略和访问控制列表(ACL)是基于资源的,因为您将它们附加到Amazon S3资源。

     

用户政策 - 您可以使用IAM管理对Amazon S3资源的访问。您可以在帐户中创建IAM用户,组和角色,并将访问策略附加到他们,授予他们访问AWS资源的权限,包括Amazon S3。

     

当Amazon S3收到请求时,它必须评估所有访问策略以确定是否授权或拒绝该请求。有关Amazon S3如何评估这些策略的更多信息,请参阅How Amazon S3 Authorizes a Request

     

- https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-overview.html

这解释了明显矛盾的行为,正如你在评论中所指出的那样:

  

“此外,文档here似乎非常清楚地否认了未明确允许的内容。”

文档是正确的,并且您是正确的,除非您未能考虑明确允许的内容包含资源所有者(帐户所有者)对于存储桶而言,已经明确允许。

如果存储桶拥有者允许所有人执行特定操作......那么,Lambda函数的执行角色是每个人的一部分。因此,Lambda执行角色策略中的访问权限将是多余且不必要的,因为帐户所有者已经将权限授予所有人。角色策略中缺少明确的AWS_SESSION_TOKEN意味着存储桶策略中的显式Deny允许建议的操作发生。

  

另外,策略模拟器确实给了我预期的行为。”

策略模拟器不会对真实服务进行真正的调用,所以当像资源桶这样的资源有自己的策略时,它必须明确地包含资源本身的策略。模拟。

  

要在模拟器中使用基于资源的策略,您必须在模拟中包含资源,并选中复选框以在模拟中包含该资源的策略。

     

https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_testing-policies.html

否则,您只是孤立地测试角色策略。

请注意,有关用于列出存储桶中对象的S3策略的文档存在一些混淆。 The action for allowing this in IAM policies is s3:ListBucket尽管Node.JS SDK方法调用是listObjects()。策略模拟器中有一个名为Allow的操作,它可能是计划/未来功能的一部分,也可能只是一个错误,因为最后检查并不对应于S3的有效IAM策略操作。在S3 section of the IAM User Guide中,ListObjects已正确地超链接到S3 API参考中的列表对象操作,但s3:ListBucket是一个循环超链接,直接返回到IAM用户指南中的同一页面(a链接到无处)。到目前为止,我还没有成功地在AWS上找到解释或纠正这种差异的人。