Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lambda functions with s3 event sources are publically accessible #1039

Closed
bruceduhamel opened this issue Sep 16, 2021 · 4 comments
Closed

Lambda functions with s3 event sources are publically accessible #1039

bruceduhamel opened this issue Sep 16, 2021 · 4 comments
Labels
auto-closed [Bot] Closed, details in comments next-release-candidate no-activity [Bot] Closing soon if no new activity

Comments

@bruceduhamel
Copy link

bruceduhamel commented Sep 16, 2021

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

I'm still looking into it, but for zappa deploy and update, we call core.create_event_permission. This method calls the lambda client add_permission method. If updated to include the SourceAccount argument with the account id the resource policy is created as expected during deploys and updates.

SourceAccount (string) -- For Amazon S3, the ID of the account that owns the resource. Use this together with SourceArn to ensure that the resource is owned by the specified account. It is possible for an Amazon S3 bucket to be deleted by its owner and recreated by another account.

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:*"
                    ]
                }
            }
        ]
    }
}
  1. create a lambda function file named lambda_handler.py with the following content:
def lambda_handler(event, context):
    pass
  1. zappa deploy test
  2. open the resource policy in the aws console by navigating to the lambda function / configuration / permissions / resource policy
  3. 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"
        }
      }
    }
  ]
}
  1. 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.
  2. 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

  • Zappa version used: 0.53.0
  • Operating System and Python version: Ubuntu 20.04, python 3.8.10
  • The output of pip freeze: argcomplete==1.12.3
    boto3==1.18.42
    botocore==1.21.42
    certifi==2021.5.30
    cfn-flip==1.2.3
    charset-normalizer==2.0.5
    click==8.0.1
    durationpy==0.5
    future==0.18.2
    hjson==3.0.2
    idna==3.2
    jmespath==0.10.0
    kappa==0.6.0
    pep517==0.11.0
    pip-tools==6.2.0
    placebo==0.9.0
    python-dateutil==2.8.2
    python-slugify==5.0.2
    PyYAML==5.4.1
    requests==2.26.0
    s3transfer==0.5.0
    six==1.16.0
    text-unidecode==1.3
    toml==0.10.2
    tomli==1.2.1
    tqdm==4.62.2
    troposphere==3.0.3
    urllib3==1.26.6
    Werkzeug==0.16.1
    wsgi-request-logger==0.4.6
    zappa==0.53.0
  • Link to your project (optional):
  • Your zappa_settings.json:
    See steps to reproduce
@anettleship
Copy link
Contributor

Thanks for fixing this, @ghostmaster-ai are you working to bring your work from Zappa2 back into Zappa now it has been undeprecated?

@monkut
Copy link
Collaborator

monkut commented Aug 17, 2022

I've had to adjust this manually as well in the past.
I think zappa should add the following condition by default:

      "Condition": {
        "StringEquals": {
          "AWS:SourceAccount": "{Project Creator Account}"
        },

Copy link

github-actions bot commented Apr 3, 2024

Hi there! Unfortunately, this Issue has not seen any activity for at least 90 days. If the Issue is still relevant to the latest version of Zappa, please comment within the next 10 days if you wish to keep it open. Otherwise, it will be automatically closed.

@github-actions github-actions bot added the no-activity [Bot] Closing soon if no new activity label Apr 3, 2024
Copy link

Hi there! Unfortunately, this Issue was automatically closed as it had not seen any activity in at least 100 days. If the Issue is still relevant to the latest version of Zappa, please open a new Issue.

@github-actions github-actions bot added the auto-closed [Bot] Closed, details in comments label Apr 13, 2024
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Apr 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-closed [Bot] Closed, details in comments next-release-candidate no-activity [Bot] Closing soon if no new activity
Projects
None yet
Development

No branches or pull requests

3 participants