When writing serverless functions, the developer oversees the code, the application logic, and the application layer configurations while co-managing shared security responsibilities with a serverless computing provider, in this case, AWS Lambda.
In the circumstance that your Lambda functions are left unassessed and unsecured for potential risk, they can inherit security vulnerabilities that can have severe repercussions on your events and identity access management. Let’s examine the four most common security risks that make unsecured Lambda functions vulnerable:
Authentication and Access Control
An application built using serverless functions contains numerous AWS Lambda functions. Each programmatic function is distinct and serves a specific purpose. When spliced together and orchestrated, the functions create the overall business logic where the configuration and management of servers are invisible to the end user. Some functions collect, store and dynamically display real-time data, while other functions connect payment and API gateways to automate transactions.
Additionally, some functions “consume events” or subscribe to an event that triggers your functions to run. An event triggering a Lambda function could be almost anything, from an HTTP request through API Gateway, a schedule managed by an EventBridge rule, an IoT (Internet of Things) event, or an S3 event.
In other words, when using AWS as your cloud provider, an “event” is any occurrence in AWS that triggers a Lambda function, like an S3 bucket upload, an SNS topic or HTTP endpoints created via API Gateway. You can imagine the security complexity arising from each function having different expected outcomes, triggered from a different event and with no notion of the other moving parts.
Broken authentication in serverless architectures results from the poor application of identity and access controls management, especially with multiple services, events, triggers, and no continuous flow.
Any unauthenticated and unauthorized access to functions can break the system’s business logic and flow of execution. Applying rigorous AuthN+AuthZ schemes that provide robust access controls to every function, event types, and triggers must be managed carefully to close the door on the possibility of a security breach.
Function Event-Data Injection
On AWS, Lambda functions must be connected to events from several sources that trigger their execution. The overabundance of event sources expands the attack surface. Securing Lambda functions from event-data injections then becomes a complex task. The type of event and its source determines whether the event input is controlled by an attacker. Some types of event data are resistant to corruption by an attacker.
For example, standard notifications of database events. But others such as HTTP/S API calls are much more vulnerable to being hijacked for malicious purposes. A few common types of injection flaws in serverless architectures are operating system (OS) command injection, function runtime code injection (Node.js/JavaScript, Python, Java, C#, Golang), SQL injection, NoSQL injection and Pub/Sub message data tampering (MQTT data injection).
Identity Access Management
For Lambda functions, AWS manages the underlying infrastructure and application platform, the operating system, and the execution environment. The DevOps team handles continuous security in the SDLC (software development life cycle), starting from code security, as well as identity and access management to the Lambda service and within their serverless functions.
As a rule of thumb, granting permissions and access should follow the “principle of least privilege,” which essentially means that the Lambda functions should only be assigned those privileges that are essential to performing their intended logic.
In a real-world scenario, this is easier said than done. For example, if you need to write an IAM policy for a Lambda function that needs access to the DynamoDB service, you need to work through over 50 different DynamoDB permissions and give least-privilege access to exactly those sets of permissions that the Lambda function would need to execute on its intended logic and nothing else. You must also work through the condition keys that allow granting of access under certain conditions.
Now consider another very realistic scenario where your serverless application is made up of dozens, if not hundreds, of different Lambda functions. The sheer number makes managing function permissions and roles a daunting task. If you lean on a single permission model or security role for all Lambda functions, you will inadvertently grant all functions full access, thereby creating a security risk.
Another issue to note is the possibility of an IAM credential leak due to an IAM policy misconfiguration. Lambda functions use temporary security credentials when they are granted an IAM role. When the function executes, it receives access tokens from the AWS security token service. An attacker who maliciously gains access to the tokens can remotely impersonate the function from outside the Lambda environment and retrieve any resources available to it.
Logging and Monitoring
Serverless monitoring allows developers to gain important insights on each execution and event. AWS provides the logging service CloudTrail and the monitoring service CloudWatch. AWS CloudTrail is enabled by default on every AWS account once the account is created. When a supported event activity occurs in AWS Lambda, that activity is stored in a CloudTrail event, along with other AWS service events in the “Event History” console.
Lambda automatically monitors the functions on your behalf and reports metrics through Amazon CloudWatch. From a security standpoint, it’s critical to log and monitor security-related events to detect and mitigate risks in real-time. While it’s true that both tools are extremely valuable, for some developers the tools’ out-of-the-box configurations aren’t always conducive to capturing the entire security event audit trail that is bespoke to your application.
Ensuring Security Is a Shared Responsibility
AWS provides a robust set of security controls for its users. But it is up to the users to make the most of these built-in capabilities. The AWS Lambda console helps secure your Lambda functions by allowing you to view and manage your Lambda functions, including their configuration files and IAM roles. However, to eliminate the possibility of inheriting vulnerabilities in your Lambda functions, it’s important to ensure that only verified code from trusted publishers is deployed within Amazon Lambda and vulnerable functions are weeded out. These are key to a safer deployment.
Securing AWS Lambda Serverless Functions
It’s evident that AWS Lambda is undoubtedly at the heart of serverless applications. The “stateless” nature of Lambda functions, with no affinity to the underlying infrastructure, allows you to focus solely on what you love doing most—writing code. But now that you are aware of the security risks that can riddle your serverless computing environment, the next step is to avail yourself of a serverless security solution that helps you mitigate the risks. These are some must-have capabilities to look for in your ideal serverless security solution:
You would begin with making sure the solution can connect to your AWS account and scans serverless your Lambda functions for security issues and vulnerabilities.
After scanning the functions, it should be able to a risk score against each function, ranking all functions based on the score.
The risk scoring should ideally be based on the function’s code and the cloud configuration metadata and take the following into account:
- Authentication and authorization of functions, verifying identified and authorized function triggers.
- Code vulnerabilities in open-source packages or dependencies.
- The presence of secrets, such as keys and passwords, in the function’s code or environment variables.
- Inappropriate or excessive permissions granted to functions.
- Functions with public-access exposure and access to data sources that may be targeted for exfiltration.
- Any dead or inactive functions.
You should be able to manually trigger a scan at any time, or you should be able to schedule scans to be run at regular intervals. You should then be able to configure policies based on the types of risks that apply to your AWS Lambda environment. And lastly, if the risk score rises to an unacceptable level, you should be able to get alerted on exactly which serverless function triggered the alert.
Top comments (2)
Hello Tricia.
Thx for your effort.
I'm wondering if you could provide a few examples of tools that can help with the last section of your article?
Hi Tomasz,
Thanks for the note. I would say Panoptica by Cisco is a great example of an easy-to-implement and easy-to-use tool that inspects serverless functions for vulnerabilities. You can try it for free to get a feel for how it works. Check this out: panoptica.app/quick-start