Use the Conformity Knowledge Base AI to help improve your Cloud Posture

Enable IAM Authentication for Lambda Function URLs

Trend Micro Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 750 automated best practice checks.

Risk Level: High (act today)
Rule ID: Lambda-010

Ensure that your function URLs are secured with IAM authentication (AWS_IAM) in order to allow only authenticated IAM users and roles to invoke your Amazon Lambda functions via function URLs.

This rule resolution is part of the Conformity Security & Compliance tool for AWS.

Security

A function URL should be used with caution, and only applied on Lambda functions with appropriate access control in place. When a function URL is configured with IAM authentication, Amazon Lambda uses Identity and Access Management (IAM) service to authenticate and authorize requests based on the IAM principal's identity policy and the function's resource-based policy. If the function URL is not using IAM authentication, Lambda doesn't perform any authentication before invoking your function, therefore to prevent exposing your function to the public and avoid implementing a custom authorization logic, your function URL should be configured with IAM authentication.


Audit

To determine if your Amazon Lambda functions are using IAM authentication for function URLs, 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 Function URL from the left menu.

06 In the Function URL section, check the Auth type configuration attribute value. If the Auth type attribute value is set to NONE, the selected Amazon Lambda function is not using IAM authentication for function URLs, therefore the function URL is public and anyone with the URL can access your Lambda function.

07 Repeat steps no. 4 – 6 for each Lambda function available within the current AWS region.

08 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 name of each Amazon Lambda function 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-export-user-data   |
|  cc-get-s3-log-data    |
+------------------------+

03 Run list-function-url-configs command (OSX/Linux/UNIX) using the name of the Amazon Lambda function that you want to examine as the identifier parameter and custom query filters to describe the type of the authentication used by the function URL:

aws lambda list-function-url-configs
  --region us-east-1
  --function-name cc-export-user-data
  --query 'FunctionUrlConfigs[*].AuthType'

04 The command output should return the function URL authentication type:

[
  "NONE"
]

If the list-function-url-configs command output returns "NONE", as shown in the output example above, the selected Amazon Lambda function is not using IAM authentication for function URLs, therefore the function URL is publicly accessible and anyone that knows the URL can access your Lambda function.

05 Repeat steps no. 3 and 4 for each Lambda function available in the selected AWS region.

06 Change the AWS 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 limit access to your Amazon Lambda function URL to authenticated IAM users and roles, perform the following operations:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
	"AWSTemplateFormatVersion": "2010-09-09",
	"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",
										"ec2:DescribeNetworkInterfaces",
										"ec2:CreateNetworkInterface",
										"ec2:DeleteNetworkInterface",
										"ec2:DescribeInstances",
										"ec2:AttachNetworkInterface"
									],
									"Resource": "*"
								}
							]
						}
					}
				]
			}
		},
		"LambdaFunction": {
			"Type": "AWS::Lambda::Function",
			"Properties": {
				"FunctionName": "cc-app-worker-function",
				"Handler": "lambda_function.lambda_handler",
				"Role": {
					"Fn::GetAtt": [
						"FunctionExecutionRole",
						"Arn"
					]
				},
				"Code": {
					"S3Bucket": "cc-lambda-functions",
					"S3Key": "worker.zip"
				},
				"Runtime": "python3.9",
				"MemorySize": 1024,
				"Timeout": 45,
				"VpcConfig": {
					"SecurityGroupIds": [
						"sg-0abcd1234abcd1234"
					],
					"SubnetIds": [
						"subnet-abcd1234",
						"subnet-1234abcd"
					]
				}
			}
		},
		"LambdaUrl": {
			"Type": "AWS::Lambda::Url",
			"Properties": {
				"TargetFunctionArn": {
					"Fn::GetAtt": [
						"LambdaFunction",
						"Arn"
					]
				},
				"AuthType": "AWS_IAM"
			}
		}
	}
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
	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
					- ec2:DescribeNetworkInterfaces
					- ec2:CreateNetworkInterface
					- ec2:DeleteNetworkInterface
					- ec2:DescribeInstances
					- ec2:AttachNetworkInterface
					Resource: '*'
	LambdaFunction:
		Type: AWS::Lambda::Function
		Properties:
		FunctionName: cc-app-worker-function
		Handler: lambda_function.lambda_handler
		Role: !GetAtt 'FunctionExecutionRole.Arn'
		Code:
			S3Bucket: cc-lambda-functions
			S3Key: worker.zip
		Runtime: python3.9
		MemorySize: 1024
		Timeout: 45
		VpcConfig:
			SecurityGroupIds:
			- sg-0abcd1234abcd1234
			SubnetIds:
			- subnet-abcd1234
			- subnet-1234abcd
	LambdaUrl:
		Type: AWS::Lambda::Url
		Properties:
		TargetFunctionArn: !GetAtt 'LambdaFunction.Arn'
		AuthType: AWS_IAM

Using Terraform (AWS Provider)

01 Terraform configuration file (.tf):

terraform {
	required_providers {
		aws = {
		  source  = "hashicorp/aws"
		  version = "~> 4.0"
		}
	}

	  required_version = ">= 0.14.9"
  }

  provider "aws" {
	  profile = "default"
	  region  = "us-east-1"
  }

  resource "aws_iam_role" "lambda-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-app-worker-function"
	  s3_bucket        = "cc-lambda-functions"
	  s3_key           = "worker.zip" 
	  role             = aws_iam_role.lambda-execution-role.arn
	  handler          = "lambda_function.lambda_handler"
	  runtime          = "python3.9"
	  memory_size      = 1024
	  timeout          = 45   
	  vpc_config {
		subnet_ids         = [ "subnet-01234abcd1234abcd", "subnet-0abcd1234abcd1234" ]
		security_group_ids = [ "sg-0abcd1234abcd1234" ]
	  }
  }

  resource "aws_lambda_function_url" "lambda-function-url" {
	  function_name      = aws_lambda_function.lambda-function.function_name
	  qualifier          = "cc-lambda-url-alias"
	  authorization_type = "AWS_IAM"
  }

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 reconfigure.

05 Select the Configuration tab and choose Function URL from the left menu.

06 In the Function URLsection, choose Edit to modify the function URL configuration defined for the selected Amazon Lambda function.

07 On the Configure Function URL configuration page, perform the following actions:

  1. Choose AWS_IAM for the Auth type to allow only authenticated Amazon IAM users and roles to make requests to the function URL.
  2. To control access to your function URL from other origins, select the Configure cross-origin resource sharing (CORS) checkbox. To configure CORS for your function URL, perform the following:
    • For Allow origin, specify the origin(s) that can access your function URL.
    • For Expose headers, provide the headers that you want to expose to the origin(s) specified at the previous steps.
    • For Allow headers, choose the HTTP headers that the specified origins can include in the requests made to your function URL.
    • For Allow methods, select the HTTP methods allowed when calling your function URL.
    • For Max age, set the maximum amount of time (in seconds) that browsers can cache the results of a preflight request.
    • For Allow credentials, choose whether to allow credentials in the requests made to your function URL.
  3. Choose Save to apply the changes and enable IAM authentication for your function URL.

08 Repeat steps no. 4 – 7 to reconfigure the function URL for each Amazon Lambda function available within the current AWS region.

09 Change the AWS cloud region from the navigation bar and repeat the Remediation process for the other regions.

Using AWS CLI

01 Run update-function-url-config command (OSX/Linux/UNIX) to enable IAM authentication (i.e. allow only authenticated IAM users and roles to make requests to the function URL) for your Amazon Lambda function URL and configure Cross-Origin Resource Sharing (CORS):

aws lambda update-function-url-config
  --region us-east-1
  --function-name cc-export-user-data
  --auth-type AWS_IAM
  --cors 'AllowOrigins="https://www.example.com",AllowMethods="*",ExposeHeaders="keep-alive",MaxAge=3600,AllowCredentials=false'

02 The command output should return the new, secure configuration available for your function URL:

{
	"FunctionUrl": "https://abcd1234abcd1234abcd1234abcd1234.lambda-url.us-east-1.on.aws/",
	"FunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:cc-export-user-data",
	"AuthType": "AWS_IAM",
	"Cors": {
		"AllowCredentials": false,
		"AllowMethods": [
			"*"
		],
		"AllowOrigins": [
			"https://www.example.com"
		],
		"ExposeHeaders": [
			"keep-alive"
		],
		"MaxAge": 3600
	},
	"CreationTime": "2022-06-22T17:04:40.449428Z",
	"LastModifiedTime": "2022-06-22T17:29:41.587910Z"
}

03 Repeat steps no. 1 and 2 to reconfigure the function URL for each Amazon Lambda function available in the selected AWS region.

04 Change the AWS cloud region by updating the --region command parameter value and repeat steps no. 1 – 3 to perform the Remediation process for other regions.

References

Publication date Jul 5, 2022

Unlock the Remediation Steps


Free 30-day Trial

Automatically audit your configurations with Conformity
and gain access to our cloud security platform.

Confirmity Cloud Platform

No thanks, back to article

You are auditing:

Enable IAM Authentication for Lambda Function URLs

Risk Level: High