Serverless computing or function-based computing is a way by which customers can develop backend systems or event-driven pipelines without worrying about the underlying infrastructure, which is managed by the cloud provider. It is billed based on the invocations and the duration of execution. While powerful, serverless computing has special security considerations that organizations must address. This is the second of three blogposts to discuss how best to secure your serverless computing environment in AWS Lambda.

Security Considerations with AWS Lambda

Although AWS Lambda is a serverless compute service, there are security considerations to keep in mind. Some of the most common practices to protect against potential security issues are covered below.

Block Public Access to Amazon S3 Buckets

Amazon S3 provides integrations with AWS Lambda. You can define triggers so that when a file is created or moved in a bucket, an AWS Lambda function is executed. Buckets are top-level objects that store other objects within them and can be accessed privately from both an AWS environment and the public internet.

If a bucket is available over the internet, a third party might be able to upload malicious files to the public Amazon S3 bucket and gain access to your AWS environment. It is a best practice and the AWS default setting to block all public access to Amazon S3 buckets and make sure there are no buckets accessible from the internet.

Figure 4: Blocking public access to Amazon S3 buckets

Limit Roles per Lambda

AWS Lambda requires an IAM service role that allows it to access other services within your AWS ecosystem. It is a best practice to follow the principle of least privilege, create separate roles for each and every AWS Lambda function; and provide only the fewest permissions necessary for each of those roles. This means every AWS Lambda function will have access to only those services it is designed to communicate with.

The code below highlights two IAM policy statements. The first statement allows the IAM role to list the Amazon S3 bucket, and the second allows it to only read objects under a specific directory within the Amazon S3 bucket.

{

    sid     = "AllowListing"

    effect  = "Allow"

    actions = [

      "s3:ListBucket"

    ]

    resources = [

      "arn:aws:s3:::data-prod-bucket"

    ]

    principals {

      identifiers = ["arn:aws:iam::<ACCOUNT_ID>:role/lambda-function-role"]

      type        = "AWS"

    }

}




{

    sid     = "AllowRead"

    effect  = "Allow"

    actions = [

      "s3:GetObjectVersion",

      "s3:GetObject"

    ]

    resources = [

      "arn:aws:s3:::data-prod-bucket/app-directory/*"

    ]

    principals {

      identifiers = ["arn:aws:iam::<ACCOUNT_ID>:role/lambda-function-role"]

      type        = "AWS"

    }

}

Use AWS Systems Manager to Share Credentials

Applications sometimes need external credentials, for example, database credentials or API secret keys. There is an option in AWS Lambda to provide such credentials using environment variables. But environment variables in AWS Lambda aren’t encrypted and need to be managed via your application code.

A better approach to sharing external credentials with a function is to leverage the AWS Systems Manager Parameter Store. You can use this to store encrypted and sensitive credentials, as well as to define IAM policies so that Lambda functions can read these credentials from the Parameter Store.

Follow the AWS Shared Responsibility Model

According to the AWS shared responsibility model, both customers and AWS are responsible for securing the cloud environment. AWS is primarily responsible for securing the infrastructure, networking, and data centers. Whereas it is the responsibility of the customer to secure data within the cloud environment. This means customers need to secure their applications, routinely patch and update their EC2 machines, and rotate credentials and other sensitive information on a regular basis.

Figure 5: AWS shared responsibility model (Source: AWS)

Common AWS Unauthorized Event Examples

A common perception in the market is that since AWS Lambda is serverless, it’s “secure by design,” as security blogger Aphinya Dechalert says, and therefore its security does not need any enhancements. However, this is not the case: as mentioned above, while AWS is responsible for the security of the infrastructure, application security is still the customer’s responsibility. Several third-party security teams have uncovered scenarios that revealed security issues. A few examples are discussed below.

OS Command Injection

One of the most common methods of an unauthorized event is OS command injection. Here, the unauthorized user mostly combines a part of the AWS Lambda URL with an executable OS command. Constructing operating system or shell commands with unsanitized user input can lead to inadvertently running malicious code. For example, security expert Stefano Chierici reports that linking together part of an AWS Lambda URL with multiple commands using semicolons is a common way that unauthorized users could execute arbitrary commands for remote code execution.

Compromised AWS Access Key and Secret Key

While developing applications on the local machine, developers make use of AWS Access Key IDs and secret access keys to talk to various services and resources within AWS. Ideally, you should only use temporary credentials via AWS IAM Identity Center. However, there may be times when these secret credentials have gotten packed with the application codebase and pushed to a public repository. This is dangerous, as a third party might be able to gain access to your AWS environment using the publicly available credentials. Be sure to check that such secrets are never stored in your application codebase.

IAM Full Access Exploitations

While developing applications with AWS Lambda, developers often grant full access to a service or resource for the function. But in practice, this is an anti-pattern and needs to be handled efficiently. For example, if your AWS Lambda functions need to access data from an Amazon S3 bucket, you should define the IAM policy that would explicitly grant access only to that specific bucket and not to any other buckets within your AWS environment.

Also, if the function is meant to only read data from the bucket, then modify the IAM policy to read-only.

AWS Lambda Malware

The experts at Cado Security detected a new piece of malware, known as Denonia, which specifically targeted AWS Lambda functions. It contained a customized variant of the open source XMRig mining software. Researchers so far have been unable to assess how the malware entered the AWS Lambda environment. Regardless, as a best practice, customers should only use temporary credentials with AWS Lambda functions, and also use security tools that 1) are constantly watching for overly permissive IAM roles used by functions, 2) can identify third-party security issues and unused functions, and 3) can locate hard-coded credentials, secrets, and other sensitive information. .

You may also like