- Knowledge Base
- Amazon Web Services
- AWS Lambda
- Function Exposed
Identify any publicly accessible Amazon Lambda functions and update their access policy in order to protect against unauthorized users that are sending requests to invoke these functions.
This rule can help you with the following compliance standards:
- PCI
- GDPR
- APRA
- MAS
For further details on compliance standards supported by Conformity, see here.
This rule can help you work with the AWS Well-Architected Framework.
This rule resolution is part of the Conformity Security & Compliance tool for AWS.
Allowing anonymous users to invoke your Amazon Lambda functions is considered a bad practice and can lead to data exposure, data loss, and unexpected charges on your AWS bill. To prevent any unauthorized invocation requests to your Lambda functions, restrict access only to trusted entities by implementing the appropriate permissions policies.
Audit
To identify any exposed Amazon Lambda functions currently available within your AWS cloud account, perform the following operations:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon Lambda console at https://console.aws.amazon.com/lambda/.
03 In the left navigation panel, under AWS Lambda, choose Functions.
04 Click on the name (link) of the function that you want to examine.
05 Select the Configuration tab and choose Permissions from the left menu.
06 In the Resource-based policy section, choose View policy document to access the resource-based policy attached to the selected function.
07 Within the Resource-based policy document box, identify the "Principal" element defined for each policy statement and check the element value. If the "Principal" element has one of the following values: "*" or { "AWS": "*" }, the "Effect" element is set to "Allow", and the policy statement is not using a "Condition" clause to filter the access, the selected Amazon Lambda function is exposed to anonymous access.
08 Repeat steps no. 4 – 7 for each Lambda function available within the current AWS region.
09 Change the AWS cloud region from the console navigation bar and repeat the Audit process for other regions.
Using AWS CLI
01 Run list-functions command (OSX/Linux/UNIX) to list the names of all the Amazon Lambda functions available in the selected AWS region:
aws lambda list-functions --region us-east-1 --output table --query 'Functions[*].FunctionName'
02 The command output should return a table with the requested function name(s):
-------------------------- | ListFunctions | +------------------------+ | cc-process-app-queue | | cc-export-user-data | | cc-get-ec2-log-data | +------------------------+
03 Run get-policy command (OSX/Linux/UNIX) using the name of the Amazon Lambda function that you want to examine as the identifier parameter, to describe the resource-based policy attached to the selected Lambda function:
aws lambda get-policy --region us-east-1 --function-name cc-process-app-queue --output text --query 'Policy'
04 The command output should return the requested resource-based policy:
{ "Version": "2012-10-17", "Id": "default", "Statement": [ { "Sid": "PublicAccess", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:us-east-1:123456789012:function:cc-sqs-poller" } ] }
Identify the "Principal" element defined for each policy statement and check the element value. If the "Principal" element has one of the following values: "*" or { "AWS": "*" }, the "Effect" element is set to "Allow", and the policy statement is not using a "Condition" clause to filter the access, the selected Amazon Lambda function is exposed to everyone.
05 Repeat steps no. 3 and 4 for each Lambda function available in the selected AWS region.
06 Change the AWS cloud region by updating the --region command parameter value and repeat steps no. 1 – 5 to perform the Audit process for other regions.
Remediation / Resolution
To update the resource-based policies associated with your Amazon Lambda functions in order to allow function invocation only from trusted entities, perform the following operations:
Using AWS CloudFormation
01 CloudFormation template (JSON):
{
"AWSTemplateFormatVersion":"2010-09-09",
"Description": "Block Public Access - Allow Invocation from a Trusted AWS Account",
"Resources":{
"FunctionExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "LambdaExecutionRole",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": [ "lambda.amazonaws.com" ]
},
"Action": [ "sts:AssumeRole" ]
}]
},
"Path": "/",
"Policies": [{
"PolicyName": "AWSLambdaBasicExecutionRole",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}]
}
}]
}
},
"ConsumerFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"FunctionName": "cc-process-app-queue",
"Handler": "lambda_function.lambda_handler",
"Role": {
"Fn::GetAtt": [
"FunctionExecutionRole",
"Arn"
]
},
"Code": {
"S3Bucket": "cc-lambda-functions",
"S3Key": "worker.zip"
},
"Runtime": "python3.9",
"MemorySize" : 1024,
"Timeout": 30
}
}
},
"TrustedAccessPermission": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": {
"Fn::GetAtt": [
"ConsumerFunction",
"Arn"
]
},
"Action": "lambda:InvokeFunction",
"Principal": "123412341234"
}
}
}
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09'
Description: Block Public Access - Allow Invocation from a Trusted AWS Account
Resources:
FunctionExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: LambdaExecutionRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: AWSLambdaBasicExecutionRole
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: '*'
ConsumerFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: cc-process-app-queue
Handler: lambda_function.lambda_handler
Role: !GetAtt 'FunctionExecutionRole.Arn'
Code:
S3Bucket: cc-lambda-functions
S3Key: worker.zip
Runtime: python3.9
MemorySize: 1024
Timeout: 30
TrustedAccessPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt 'ConsumerFunction.Arn'
Action: lambda:InvokeFunction
Principal: '123412341234'
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.27"
}
}
required_version = ">= 0.14.9"
}
provider "aws" {
profile = "default"
region = "us-east-1"
}
resource "aws_iam_role" "function-execution-role" {
name = "LambdaExecutionRole"
path = "/"
managed_policy_arns = [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" ]
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow"
}
]
}
EOF
}
resource "aws_lambda_function" "lambda-function" {
function_name = "cc-process-app-queue"
s3_bucket = "cc-lambda-functions"
s3_key = "sqs-consumer.zip"
role = aws_iam_role.function-execution-role.arn
handler = "lambda_function.lambda_handler"
runtime = "python3.9"
memory_size = 1024
timeout = 30
}
# Block Public Access - Allow Invocation from a Trusted AWS Account
resource "aws_lambda_permission" "trusted-access-permission" {
statement_id = "RestrictPublicAccess"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.lambda-function.function_name
principal = "123412341234"
}
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon Lambda console at https://console.aws.amazon.com/lambda/.
03 In the left navigation panel, under AWS Lambda, choose Functions.
04 Click on the name of the function that you want to reconfigure.
05 Select the Configuration tab and choose Permissions from the left menu.
06 In the Resource-based policy section, perform the following actions:
- Under Policy statements, select the policy statement that allows anonymous access, and choose Delete to remove the non-compliant statement from the resource-based policy attached. Within the Delete statement confirmation box, choose Remove to confirm the action.
- Choose Add permissions to add a new policy statement that grants permissions to a trusted entity only. On the Add permissions page, configure the new policy statement based on your requirements in order to grant access to another AWS account, IAM user, IAM role, or to another AWS service. Choose Save to apply the changes.
07 Repeat steps no. 4 – 6 for each Lambda function that allows anonymous access, available within the current AWS region.
08 Change the AWS cloud region from the console navigation bar and repeat the Remediation process for other regions.
Using AWS CLI
01 Run remove-permission command (OSX/Linux/UNIX) to remove the permission statement that allows anonymous access via the resource-based policy associated with the selected function, using the policy statement ID as the identifier parameter. The following command request example removes an individual policy statement identified by the ID "FullAccess" for an Amazon Lambda function named "cc-process-app-queue" (the command does not produce an output):
aws lambda remove-permission --region us-east-1 --function-name cc-process-app-queue --statement-id FullAccess
02 Run add-permission command (OSX/Linux/UNIX) to add a new policy statement that grants permission to a trusted AWS account to invoke the selected function (choose the action to allow based on your requirements). The ID of the trusted AWS account is provided as the value of the --principal command parameter. The --principal can be also another AWS account, IAM user, IAM role, or another AWS service such as S3 or SNS:
aws lambda add-permission --region us-east-1 --function-name cc-process-app-queue --statement-id TrustedAccess --principal 123412341234 --action lambda:InvokeFunction
03 The command output should return the newly created policy statement:
{ "Statement": "{\"Sid\":\"TrustedAccess\",\"Resource\":\"arn:aws:lambda:us-east-1:123456789012:function:cc-process-app-queue\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"123412341234\"},\"Action\":[\"lambda:InvokeFunction\"]}" }
04 Repeat steps no. 1 – 3 for each Lambda function that allows anonymous access, available in the selected AWS region.
05 Change the AWS cloud region by updating the --region command parameter value and repeat steps no. 1 – 4 to perform the Remediation process for other regions.
References
- AWS Documentation
- AWS Lambda FAQs
- Getting started with Lambda
- Using resource-based policies for Lambda
- AWS Command Line Interface (CLI) Documentation
- lambda
- list-functions
- get-policy
- add-permission
- remove-permission
- AWS Blog(s)
- Easy Authorization of AWS Lambda Functions
- CloudFormation Documentation
- AWS Lambda resource type reference
- Terraform Documentation
- AWS Provider