Securing AWS Lambda Functions with Contrast Security

Jekayin-Oluwa
8 min readDec 30, 2022
Two Gray Bullet Security Cameras On A Wall
Courtesy: Scott Webb via Pexels

Introduction

Serverless technology is being widely adopted by companies globally as they seek to develop agile applications. Serverless computing enables developers to focus more on code and less on software tools and hardware as they seek to save costs and build scalable applications.

Serverless abstracts the layer of provisioning and maintaining infrastructure and other server management tasks. Serverless on AWS enables you to build any backend application or service and deploy the code on AWS infrastructure without worrying about the underlying infrastructure. You get every tool and process required to run your application with high availability and automatically scale when needed. You get compute. The robust portfolio of serverless services on AWS begins with AWS Lambda, and it helps you access several other AWS products and services for compute, integration, and data stores. Some popular AWS serverless tools are AWS Lambda, Amazon EventBridge, AWS Step Functions, and AWS Fargate.

As beneficial as serverless applications are to companies, some security complications could arise from implementing serverless technology. We look at two of them here.

  • Inadequate monitoring and logging: more clear logging and adequate monitoring are needed to guide the developer through the interconnected services and networks. The developer may need to set up an external monitoring system to get helpful insights into the serverless stack.
  • Complicated debugging: debugging line-by-line is usually arduous compared with standard applications. Sometimes, developers resort to using verbose messages, which could humanly expose weaknesses in the system as intruders could see through the applications' internal logic when they interact directly with things like stack traces and syntax error returns.
  • Dependence on third-party systems: serverless applications often rely on services developed by 3rd parties or 3rd party code libraries. If the 3rd parties’ code is vulnerable, the serverless application also becomes susceptible to attacks.

This paper seeks to show how Contrast makes serverless security on AWS easy. It provides insights into the security challenges you face when you develop and deploy your serverless applications to AWS. It also demonstrates how you can mitigate those challenges with Contrast CodeSec.

Protect your Serverless Applications

Malicious attacks are not uncommon in serverless applications as the technology witnesses growing adoption across the industry. In addition to provisioning and maintaining servers, the cloud providers also handle security maintenance, such as applying patches and security updates in serverless applications. Without proper protection, your AWS serverless applications could be susceptible to security breaches or cyber-attacks due to the following factors:

  • Different parts on different servers: as with most major cloud providers, deploying your serverless application to AWS will result in different sections of the application on other servers. A part might be hosted as data stores on Amazon S3 or Amazon DynamoDB, some as compute functions on AWS Lambda, or another service such as Amazon Elastic Container Service (ECS). Attacks such as injection flaws could be triggered from several parts as the potential attack surface has been increased.
  • Less visibility and threat detection: the Denonia malware attack on AWS Lambda in 2022 brings to remembrance the issue of insufficient visibility and threat detection in the serverless system in the AWS environment. Serverless infrastructure needs new security tools, as existing ones aren’t modeled to provide sufficient visibility into serverless environments. AWS doesn’t offer robust solutions that fit into unique customer contexts for security observability, automated security, and detection and response.
  • Configuration issues: serverless applications depend on multiple services that need to be configured, even in the AWS ecosystem. For instance, an AWS application might need to connect with Amazon S3 buckets to get stored data. However, the configuration can be complex within AWS; therefore, errors and mistakes could happen. One of AWS users' biggest threats is misconfiguration, especially in authorization and access management. A common occurrence is that many organizations have over-privileged access and permissions to services for unconcerned parties. This way, critical data might be exposed in serverless applications. Over-privileged roles can also be abused intentionally for cyber-breaches and unintentionally to perform unintended operations.

AWS Lambda and its Security Challenges

AWS Lambda is the most popular AWS serverless tool, and you can quickly get started and run with minimal operating costs at pay-as-you-go rates. There is also a great free tier. It’s an event-driven service — running your code with an event is triggered. It is popular due to its flexibility and cost-effectiveness, making it useful for developers in several use cases and scenarios. It is also fast and well-optimized in executions. It provides support for various languages and integrates with other tools and services in the AWS ecosystem.

It is the most mature serverless tool among its competitors. Lambda is a fully hosted platform. It manages your operations and management, including capacity provisioning, version control, and code deployment. This makes it very good for building and running serverless applications. You may also avail yourself of providing HTTP endpoints over the Amazon API gateway while Lambda handles the application logic. You can hook up Amazon DynamoDB, RDS, or Aurora serverless for a fully-managed database service. You can also use the S3 for hosting assets, static website frontends, or other data, then access Lambda via the API Gateway.

Security testing can be complex in AWS Lambda, and so is development testing. End-to-end testing is practically impossible. Usually, developers test local instances of their application code before they deploy it to production. However, most of the services that your AWS Lambda function relies on are not local, they are cloud-based, and you cannot replicate the entire environment in your local machine. Therefore, you can perform complete security tests on your serverless application before deploying the code to Lambda.

Another problematic issue with AWS Lambda is tracing. You don’t get enough observability and visibility into what is running under the hood when function calls are being made. This is due to the abstraction of the infrastructure powering your serverless application on AWS. Not having access to the behind-the-scenes means that you have to rely on Amazon CloudWatch, a monitoring service provided by AWS. Then, you cannot detect issues beyond what CloudWatch logs offer.

Sample Lambda Function

This section briefly shows an arbitrary Lambda function in Java— snippets of code run on demand. The function will demonstrate how to use Contrast to scan AWS Lambda functions.

The function is a handler method. It takes in an array of two integer child elements and multiplies them. The code is shown as follows:

package awslambda;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.util.List;


public class LambdaHandlerMultiply implements RequestHandler<List<Integer>, Integer>{
Gson gson = new GsonBuilder().setPrettyPrinting().create();
@Override
public Integer handleRequest(List<Integer> event, Context context)
{
LambdaLogger logger = context.getLogger();
if ( event.size() != 2 )
{
throw new InputLengthException("Supply an array with 2 integers.");
}
int multiplierOne = event.get(0);
int multiplierTwo = event.get(1);
logger.log("EVENT: " + gson.toJson(event));
logger.log("EVENT TYPE: " + event.getClass().toString());

String query = "SELECT secret FROM Users WHERE (username = '" + multiplierOne + "' AND NOT role = 'admin')";
String query = String.format("SELECT secret FROM Users WHERE (username = '%s' AND NOT role = 'admin')", multiplierTwo);
return multiplierOne*multiplierTwo;
}

private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
}

}

The Context object in the above code provides some information that might be needed while executing in the Lambda environment.

To build the executable for the application, you need to specify the AWS Lambda dependency and the Maven Shade Plugin.

Specify the plugin like this:

<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>

Then, the dependency specification will look like the following:

<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>[2.14.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j18-impl</artifactId>
<version>[2.14.1</version>
<scope>test</scope>
</dependency>
</dependencies>

Secure Lambda Functions

CodeSec, by Contrast, is a command-line interface (CLI) security tool for serverless applications. It could optimize code in Java, JavaScript, AND .NET. It uses cloud-native architecture to understand the resources of your serverless environment and validates and prioritizes decisions.

When used in AWS Lambda projects, Contrast scans the Lambda functions in their environment for vulnerabilities in code, configuration, and dependencies.

You need to connect to your AWS account through the Contrast web application so that Contrast can create a list of resources, policies, and services in your AWS environment and their relationship to the environment. Then, Contrast scans and analyses the code, detect attack surfaces and weaknesses, and generates a report for you. It also continuously monitors the lambda function and detects vulnerabilities introduced by code changes. It reports the security scans and then suggests how to fix the issues found in the scan.

Lambda Scan Demonstration

If you run the contrast audit command on the project, you will get a terminal response with a vulnerability listed.

Terminal command:

contrast audit

The above scan report shows that there is a critical security problem which is a vulnerable library. The library is log4j, and it contains four vulnerabilities. Contrast advises updating the library to version 2.17.1 to fix the issues.

Compress the project files into a zip file to upload to AWS Lambda.

You can create a Lambda function on your AWS console to upload your .zip file. Follow the official AWS documentation instructions to set up your Lambda functions for Java.

Next, go to the Functions page of your Lambda console. Upload the deployment file. Select the function you created and upload the deployment file there.

Once you have successfully uploaded your deployment file to the Lambda function, you can then run an AWS Lambda serverless scan with the following Contrast command:

contrast lambda - function-name sampleFunction - region us-west-2

Run the contrast command. You will get a response like the following after the scanning has been completed:

The result above showed that two high vulnerabilities were discovered in the slf4j-ext and log4j-core libraries. Contrast also recommended upgrading to version 1.7.36 and 2.17.1 of the respective libraries.

Benefits of Contrast Security Serverless Scan

  • Speed and Ease: Using Contrast to scan serverless functions requires minimal specialized or advanced expertise in integration or use. It helps you to deploy easily and quickly.
  • Non-intrusive integration: Integrating Contrast does not result in any significant change or disorder in your development workflow.
  • Reduced testing time: Contrast is fast and helps you detect security problems early in the development journey. This way, you get to spend less time on testing.
  • Ensuring uptime and availability: having Contrast for scanning and continuous monitoring helps you to reduce downtime as you can observe vulnerabilities quickly and early when you deploy or when you introduce code changes in production.

Conclusion

Ensuring the security of your serverless application is of utmost importance if you have them in your organization. And understanding that serverless security needs a newer approach other than the usual methods and tools in traditional software security is critical in helping you preempt, prevent, and mitigate security challenges in the serverless domain. Contrast provides you with optimum scanning and auditing capabilities and continuously monitors your functions. It scans and provides insightful reports on vulnerabilities in your serverless code, configuration, dependencies, and their environment. It also gives you suggestions on how to fix the security issues it raises. Learn more about serverless security from the official documentation of Contrast Security.

--

--