Examining Serverless Security Strategies, Tools, and (Current) Best Practices
Serverless brings plenty to the table, but ensuring the end-to-end security of serverless applications takes thought.
Join the DZone community and get the full member experience.Join For Free
Developers and DevOps teams considering the efficiency, scalability, and cost benefits that serverless functions have to offer shouldn’t be daunted by the challenge of securing serverless applications throughout development and into production. They should take it very seriously. In this article, I will cover how to begin developing serverless functions using AWS Lambda and the best development tools to use, as well as the most effective serverless security strategies and best practices.
To begin, approaches to serverless security fall into two categories: runtime security, and static security.
As soon as an invoked serverless function begins its runtime, the clock starts on security risks. This is especially true when it comes to user input, which is a serverless function’s largest attack surface at runtime. Malicious user input can include SQL injection, designed to exploit (or even delete) data. Similarly, cross-site scripting (XSS) attacks can inject scripts onto the microVM running a serverless function. While the microVM will spin down once the function is finished executing (or times out), XSS attacks can gain a foothold within the serverless environment and launch other processes to escalate dangerous attack kill chains.
Runtime security protections that safeguard serverless functions can run either as a layer of the function or as a parallel process. These protections can verify the integrity of user input, and monitor files, processes, and connections for any abnormal or malicious behavior.
However, protections that activate with each invoked function add to the length of running time and, with serverless, every 100ms that a function runs add to the cost. Loading larger code packages and added latency also have negative impacts on performance. While I can see for some applications, for example, those responsible for financial services or critical infrastructure use cases may find the runtime security for serverless is indispensable.
In general, serverless functions already have many secure mechanisms going for them. Malicious efforts cannot alter a function’s code at runtime, because it runs only as an instance. With serverless functions running on cloud services such as AWS Lambda, the cloud service provider ensures protections from DDoS attacks, DNS attacks, TCP SYN attacks, and session hijacks. Just by following coding best practices and keeping the logic of each function simple, it’s possible to render runtime security all but unnecessary. At some future point when functions feature longer timeout values and larger code sizes, runtime protection for general serverless functions may become more necessary.
Static security protects serverless functions across two phases, a pre-execution examination phase, and a post-execution forensic analysis phase.
Pre-execution examination should adhere to the following security checklist. The first three points are unique to serverless security needs:
- Assign each function a role defining its access to resources. As a best practice, allow the minimum access privileges necessary.
- To avoid misconfigurations that present security gaps, organize all resources into a single application.
- Require distinct credentials for access to separate resources, and manage them securely.
- Closely restrict the authority to publish functions, alter routes, or change load distributions.
- Scan function libraries and address any vulnerabilities.
These safeguards must be integrated within the CI/CD pipeline and protect functions and resources at a scale far beyond what human interventions can keep up with – and thus security automation is necessary.
As for the second phase, post-execution forensic analysis is enabled by an array of cloud provider tools. For example, AWS Lambda serverless functions can be monitored and analyzed using AWS CloudWatch, AWS X-Ray, AWS Security Hub, AWS GuardDuty, or the more-recently-added Amazon Detective.
Serverless Function Development Tools and Practices
In the following examples, we will use AWS Lambda, which features native support for Java, Go, PowerShell, Python, Node.js, C#, and Ruby. If using Python, Node.js, or Ruby, it is possible to create a serverless function through the web-based AWS console, as in the screenshot below. Note that the text editor that AWS provides for writing a function is not suitable for creating larger functions that leverage multiple files, libraries, and dependencies.
Another option is to use the AWS Command Line Interface tool (CLI) to submit functions developed locally. AWS CLI installation and configuration instructions are available here.
All source code files for a locally developed function can be placed in a zip file and uploaded to the AWS CLI, as shown below.
Developing more complex services, and introducing scalable and automated static security across the CI/CD pipeline, requires more powerful development tools and a dedicated development environment. AWS lists a selection of robust developer tools here. Lumigo also offers a useful comparison of those tools.
Serverless Framework (SLS) is the most popular development tool currently, having earned over 38k stars on GitHub. AWS Serverless Application Model (SAM) is another popular choice. These tools enable developers to build a serverless project in a serverless.yml file, and translate the project to a CloudFormation template that AWS will use to create all needed resources. Specifically, both SLS and SAM offer:
- Infrastructure-as-code to define resources in CloudFormation, including the serverless function, API gateways, Amazon S3 storage, and more.
- Local function testing.
- Easy multi-stage CI/CD pipeline integration.
- Full open source modification potential.
SLS also features a list of more than 1000 existing plugins ready to vastly improve and simplify serverless function development, while also making it simple to write new plugins as needed. Below is a small sample of the plugins available.
Serverless Stack offers valuable step-by-step instructions for creating an effective serverless project using SLS. This resource enables developers to gain experience with serverless development workflows and in utilizing basic AWS components, serving as an excellent beginner’s tutorial.
Best Practices for Building Secure Serverless Functions
Here are six rules to follow in order to develop secure serverless applications:
1. Keep your code base well organized. Separate resource definitions from your functions. Leverage resources as parameters, not as hardcoded strings. Utilize code sharing, and reduce package sizes as much as possible.
Here are two examples demonstrating proper code organization. The first showcases multiple functions with shared libraries:
## one service with three function frontend, middle ware and BackEnd
serverless.common.yml # common parameter
libs/ # Shared code between functions.
Here we have another example (provided by Serverless Stack):
## shared resource like S3, Dynamo DB or IAM which not chance often put in one folder
2. Restrict identity and access management (IAM) roles to each individual’s function, adhering to the principle of least privilege.
3. Use a service such as AWS SSM Agent to manage secrets properly.
4. Each single serverless function should perform a single task. If the output of a function requires further processing, save the output to a data store and have that save action trigger a new function. Do not use a current function to call another function.
5. Minimize remote connections as much as possible. A function should mostly process input locally no matter how complex, and return the result. Remote connections add to latency and create debugging and scaling issues.
6. Reduce dependencies as much as possible. Place them in a shared layer and perform regular security scanning.
There you have it – the benefits of serverless functions and peace of mind of knowing they are secure.
Opinions expressed by DZone contributors are their own.