Miserlou / Zappa

Serverless Python
https://blog.zappa.io/
MIT License
11.89k stars 1.21k forks source link

Lambda functions with s3 event sources are publically accessible #2227

Closed bruceduhamel closed 2 years ago

bruceduhamel commented 2 years ago

Context

AWS Security Hub flags Zappa deployed lambda functions with an s3 event source as allowing public access.

PCI.Lambda.1 Lambda functions should prohibit public access

CRITICAL:
This AWS control checks whether the Lambda function policy attached to the Lambda resource prohibits public access.
Related requirements: PCI DSS 1.2.1, PCI DSS 1.3.1, PCI DSS 1.3.2, PCI DSS 1.3.4, PCI DSS 7.2.1

For directions on how to fix this issue, consult the AWS Security Hub PCI DSS documentation.
https://docs.aws.amazon.com/console/securityhub/PCI.Lambda.1/remediation

Expected Behavior

While I'm not sure this satisfies cases where there are multiple AWS accounts involved, it seems to me the default behavior should be to create private lambda functions by including the AWS:SourceAccount in the lambda resource policy conditions as shown in my steps to reproduce below.

Actual Behavior

Zappa creates lambdas that can be invoked by anyone in control of the s3 bucket leading to AWS Security Hub flagging a security finding.

Possible Fix

Steps to Reproduce

Since s3 buckets are involved and names are global, you'll need to edit references to the s3 bucket name in the below steps

  1. Create a zappa_settings.json file as below
    {
    "test": {
        "app_function": "my_project_name.lambda_handler",
        "aws_region": "us-west-2",
        "project_name": "my_project_name",
        "timeout_seconds": 900,
        "apigateway_enabled": false,
        "runtime": "python3.8",
        "keep_warm": false,
        "s3_bucket": "zappa-my-project-name",
        "events": [
            {
                "function": "lambda_handler",
                "event_source": {
                    "arn":  "arn:aws:s3:::zappa-my-project-name"
                    "events": [
                        "s3:ObjectCreated:*"
                    ]
                }
            }
        ]
    }
    }
  2. create a lambda function file named lambda_handler.py with the following content:
    def lambda_handler(event, context):
    pass
  3. zappa deploy test
  4. open the resource policy in the aws console by navigating to the lambda function / configuration / permissions / resource policy
  5. here's an example policy
    {
    "Version": "2012-10-17",
    "Id": "default",
    "Statement": [
    {
      "Sid": "redacted",
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:us-west-2:redacted:function:my-project-name-test",
      "Condition": {
        "ArnLike": {
          "AWS:SourceArn": "arn:aws:s3:::zappa-my-project-name"
        }
      }
    }
    ]
    }
  6. note the policy conditions only check if the principal is s3.amazonaws.com. This means anyone in control of the s3 bucket in the event source can trigger your lambda function. For example, if you were to delete the bucket, someone else may create a bucket with the same name, drop an object in it, and trigger your lambda.
  7. If we add the aws account ARN as a condition, the function is no longer publically invokable, and AWS security hub is satisfied
    {
    "Version": "2012-10-17",
    "Id": "default",
    "Statement": [
    {
      "Sid": "redacted",
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:us-west-2:redacted:function:my-project-name-test",
      "Condition": {
        "StringEquals": {
          "AWS:SourceAccount": "575985943108"
        },
        "ArnLike": {
          "AWS:SourceArn": "arn:aws:s3:::zappa-my-project-name"
        }
      }
    }
    ]
    }

Your Environment

bruceduhamel commented 2 years ago

Wrong repo, sorry. Migrated to https://github.com/zappa/Zappa/issues/1039