Security Threat Analysis: AWS Lambda-URLs
Ziyad Almbasher
AWS Security Research, Strategy & Leadership | AWS Community Builder_Security
/0 Intro
AWS released a new Lambda-URL functionality on April 06 2022. It allows invoking a Lambda function directly from the internet when the AUTH Type is set to NONE. The other authentication type available is AWS_IAM.
We will take a look at the security ramifications of this new feature by going through a lab, and then analyzing the results. But first, lets take a quick look at Lambda security in general.
/1 Lambda Security
AWS Lambda is a public service, meaning it can be launched inside a specific AWS account, but it lives outside of any VPCs, and such is by default and by design. When a Lambda is however placed within a VPC, it will be integrated with many of the security controls we usually work hard to implement: Security Groups, NACLs, AWS Network Firewalls, WAFs, ALBs, VPC-Endpoints and so on. The "VPC-Lambdas" will also use an Internet Gateway (attached to the VPC) or a NAT Gateway (attached to the subnets of a VPC). All in all, we have much more control over the network security architecture and traffic of a Lambda which is part of a VPC.
So why would anyone create and invoke a Lambda-URL directly from the internet without going through any API Gateways, WAFs, etc? AWS states that the need to have a No-Auth Lambda-URL functionality would be for example to use it as a Webhook handler.
/2 Lab
Let's go through the following quick lab to get a better understanding of this new feature (I suggest proceeding in a test-lab or a personal AWS account):
import boto3
??
def lambda_handler(event, context):
? ?
? ? s3 = boto3.client('s3')
? ? s3data = s3.get_object(Bucket='YourS3BucketName',? Key='secret_birthdays.txt')
? ? readdata = s3data['Body'].read()
? ? print (readdata)
? ? return readdata
Test Event Name: Reading-Output-S
Response: "01/01/1900"
{
? "Version": "2012-10-17",
? "Id": "default",
? "Statement": [
? ? {
? ? ? "Sid": "FunctionURLAllowPublicAccess",
? ? ? "Effect": "Allow",
? ? ? "Principal": "*",
? ? ? "Action": "lambda:InvokeFunctionUrl",
? ? ? "Resource": "arn:aws:lambda:ca-central-1:000000000000:function:Data-Extractor",
? ? ? "Condition": {
? ? ? ? "StringEquals": {
? ? ? ? ? "lambda:FunctionUrlAuthType": "NONE"
? ? ? ? }
? ? ? }
? ? }
? ]
}
5. Copy the Lambda URL and paste it in another browser: it should download a file with the birthday entry which was in the S3 bucket object. If it does not work, try refreshing the page a couple of times.
/3 What is happening?
So even after having in place all the below security measures in order to achieve a completely isolated and private AWS account:
with a mere 6 lines of code in a Lambda function, someone can (either through a security config/architectural mishap, or a purely malicious intent) potentially download massive amounts of sensitive production data which was never meant to be exposed directly from the internet.?
The take away here is that Lambda has made, by design, deploying code to production extremely easy, and quick. Security in a serverless world is yet another topic to continuously monitor, plan properly, and execute accordingly.
Lastly, I still think AWS should offer us a "no-internet" option for Lambdas outside a VPC, especially for outgoing traffic to the internet...
领英推荐
/4 Security Recommendations:
1. First things first, let's discover if there were any Lambda-URLs configured quietly, "under the radar":
$ aws lambda list-functions
$ aws lambda list-function-url-configs --function-name "Lambda-with-no-URL"
{
? ? "FunctionUrlConfigs": []
}
$ aws lambda list-function-url-configs --function-name "Data-Extractor"? ? ? ? ? ?
{
? ? "FunctionUrlConfigs": [
? ? ? ? {
? ? ? ? ? ? "FunctionUrl": "https://zz00000zz.lambda-url.ca-central-1.on.aws/",
? ? ? ? ? ? "FunctionArn": "arn:aws:lambda:ca-central-1:00000000000:function:Data-Extractor",
? ? ? ? ? ? "CreationTime": "01/01/1900",
? ? ? ? ? ? "LastModifiedTime": "01/01/1900",
? ? ? ? ? ? "AuthType": "NONE"
? ? ? ? }
? ? ]
}
NOTE: Don't forget to update your AWS-CLI to the latest version, otherwise the last 2 commands wont work.
2. It would be a good idea to only allow a certain list of services and IAM permissions in the master-account's AWS Organizations, and then add new functionalities or services only after having the approval of the security team. This applies to AWS accounts with no Internet or NAT gateways, and especially for production workloads and accounts.
3. Applying the following SCP in the AWS Organizations master-account towards applicable OUs, until the functionality is well understood and reviewed by the IT/Cloud security teams. Note that the following SCP will disallow the creation of any Lambda-URL, whether Auth Type is set to AWS_IAM, or to NONE):
{
? "Version": "2012-10-17",
? "Statement": [
? ? {
? ? ? "Effect": "Deny",
? ? ? "Action": [
? ? ? ? "lambda:CreateFunctionUrlConfig",
? ? ? ? "lambda:UpdateFunctionUrlConfig",
? ? ? ? "lambda:InvokeFunctionUrl",
"lambda:DeleteFunctionUrlConfig"
? ? ? ],
? ? ? "Resource": "*"
? ? }
? ]
}
4. If however the need is to allow the Auth Type to be set to AWS_IAM, then the following SCP can be used:
{
? "Version": "2012-10-17",
? "Statement": [
? ? {
? ? ? "Sid": "VisualEditor0",
? ? ? "Effect": "Deny",
? ? ? "Action": [
? ? ? ? "lambda:CreateFunctionUrlConfig",
? ? ? ? "lambda:UpdateFunctionUrlConfig"
? ? ? ],
? ? ? "Resource": "*",
? ? ? "Condition": {
? ? ? ? "StringEquals": {
? ? ? ? ? "lambda:FunctionUrlAuthType": "NONE"
? ? ? ? }
? ? ? }
? ? }
? ]
}
5. Always understand what lambdas are programmed to do and security-scan/review them. Let the security team validate their triggers, security groups, resource policies, and execution roles, especially if the lambdas were designed to access other AWS services containing important data, such as S3, databases, etc.
6. Restrict and control the IAM roles and permissions in regards to what internal employees can do with Lambdas in production and/or any environments with access to sensitive data.
7. Proceed carefully with the public AWS services which can have outgoing internet connectivity even when there are no Internet/NAT Gateways present.
8. One of my favorite AWS services (besides KMS, IAM, and surprisingly Lambdas!) is AWS PrivateLink. I would strongly advise using VPC endpoints whenever practical or possible, while having endpoint policies and Security Groups configured. Traffic which flows inside PrivateLink is encrypted by AWS.
9. Encrypt sensitive data with different KMS "service-CMKs", and only grant other AWS services permission to use those CMKs after careful considerations (code review, etc).
There are obviously more security recommendations, this list is geared more towards the lab and this topic.
/5 Conclusion
This is a good example of the dangers associated with newly released AWS services/functionalities, and why they should be investigated quickly and carefully by the security and DevSecOps teams before allowing them to be deployed or used in production.
Thank you for reading and I hope you enjoyed this article! To check out all the other articles, click here.
References: