By, Hillel Sollow, Serverless Security R&D, published May 15, 2020
Securing your serverless application can feel overwhelming, especially when there are so many micro-services simultaneously running. Do you ever have that sinking feeling in the pit of your stomach, worrying that you have forgotten something? The agonizing fear that you have left the stove on and will burn down your home?
If you are deploying serverless applications, you may be experiencing that twisting apprehension with regards to securing this relatively new tech. While we would love to reassure you that all is well, there is a good chance that you have indeed made some mistakes. Read on for the top mistakes you should avoid, when securing serverless apps.
Mistake #1: Assuming The WAF Takes Care of All Your Application Security Needs
Traditionally Web Application Firewalls (WAF) sit on at the perimeter of your network – at the ingress of the internet, protecting web or application services that are hosted in the cloud. Since a WAF is only capable of inspecting HTTP(s) traffic, and will only protect functions, which are API Gateway-triggered functions, that leaves a lot of unprotected function triggered events that are internal to the cloud network.
As an example, a WAF will not help if your functions are triggered from different events sources, such as:
- Cloud storage events (e.g. AWS S3, Google Cloud Storage, Azure Blob storage)
- Stream data processing (e.g. AWS Kinesis)
- Databases changes (e.g. AWS DynamoDB, Azure CosmosDB)
- Code modifications (e.g. AWS CodeCommit)
- Notifications (e.g., SMS, Emails, IoT)
That is not to say you should not have a WAF as a first line of defense, but it is a critical mistake to assume the WAF takes care of it all. Relying solely on a WAF leaves many gaping security holes that you must take care of with a different solution.
Mistake #2: Failing to Customize Function Permissions
Setting policies that are wider scope and more permissive than what the function needs, is a common serverless security mistake.
Failing to minimize individual function roles and permissions makes your attack surface larger than necessary. You must sit down with the developers who wrote the functions and review what each function does. Only after determining what functions actually need to do, can you properly create a unique role for each function and create a suitable permission policy.
Mistake #3: Thinking Your Code is All Your Code
OK, now that each function is permissioned correctly, with a strict focus on least privilege, you should be all set, right?
Hold it, not just yet. Our next mistake is thinking that every piece of code in your app is your code.
In what we refer to as ‘Poisoning the Well,’ attackers aim to gain more long-term persistence in your application by means of an upstream attack. Cloud-native applications tend to comprise many modules and libraries. The modules often include many other modules, so it is not uncommon for a single serverless function to include tens of thousands of lines of code from various external source, even with less than 100 lines of code your developers wrote. Today, more than 70% of application code used open source. Attackers look to include their malicious code in common projects e.g. GitHub. After poisoning the well, they patiently wait as the new version makes its way into your cloud applications. It’s not wonder that most application security controls integrate tools like Source Code Analysis (SCA) early in the development pipeline.
In 2017, Black Duck Software, a company that markets and sells SCA solutions, published a report, where researchers found that of 1,000 commonly-used applications in the enterprise, 96 percent utilized open-source software, and over 60 percent contained security vulnerabilities due to these components – Some of the bugs found were also over four years old.
Mistake #4: Thinking You Have Control Over All Your Functions
Code vulnerabilities can be mitigated through careful integration of application security in the CI/CD pipeline… but can you be certain that every function you have deployed went through your CI/CD?
Malicious functions can slip in through a variety of means, which can make securing serverless apps difficult. Means such as being deployed by a rogue employee. Additionally, the workstations of your developers could be a target for attackers, rather than the deployed apps themselves. To be fair, developers tend to be less susceptible to phishing scams than some. But accessing a workstation would enable attackers to deploy malicious functions through legitimate channels. Such functions could sneak in and wreak havoc, undetected.
Mistake #5: Looking at the Wrong Attack Indicators
As outlined in our serverless security analysis blog, visibility gets harder with serverless. The shift to serverless significantly increases the total amount of information and number of resources, which results in your inability to make sense of all the data.
Obtaining insights from this mountain of data is challenging, and as a result, so is securing serverless apps. As the quantity of functions continues to increase from hundreds to even thousands, it is more difficult to determine if everything is behaving the way it’s supposed to. Only a few hundred functions can generate billions of events in your log every day. With all that log data, it’s difficult to filter the true important and relevant signals from the irrelevant noise.
Even if you are familiar with the attack patterns that are unique to serverless apps, visually scanning and correlating this data into an attack pattern is not scalable – the human capital expenditure increase to solve the problem is not practical. This is where Artificial Intelligence, and Machine Learning helps. We’ve demonstrated the benefits of AI through a number of use cases e.g. Self-Driving Cars, and AI is now also making a big difference, finding ways to augment Cloud Security.
Mistake #6: Granting Functions All the Time in the World
Functions should have a tight runtime profile. Admittedly, crafting appropriate serverless function timeouts is often not intuitive. The maximum duration of a function can be quite specific to that function. You must consider the configured timeout versus the actual timeout. Many developers set the timeout to the maximum allowed. And why not? ¯\_(ツ)_/¯ We don’t pay for that time, so we might as well.
If an attacker is able to succeed with a code injection, they have more time available to do more damage. Shorter timeouts require them to attack more often, which we refer to as a “Groundhog Day,” attack. That makes the attack more visible.
So, shrink not just what a function can do, but how long it can run for.
Additional Serverless Security Resources
Securing serverless apps requires a variety of tools and tactics, including collaboration between the people involved in the application and the security. For more information about serverless security, please visit the Check Point What is Serverless Security page. You can also read our latest ebook, Top Serverless Security Risks and Mitigation Strategies.