According to a study by LogicMonitor, the number of applications hosted on-premises will decrease by 10%, to 27%, by 2020. In comparison, the number of cloud-native, more specifically serverless hosted applications, like AWS Lambda, Google Cloud and Microsoft Azure, will increase to 41%.
The trend to cloud, specifically serverless, and away from on-prem, is not new and of no surprise, as serverless hosted applications provide developers with a faster speed to market and allows for them to release new functionality on a more frequent basis. In addition, it can save organizations bundles in infrastructure costs. It has however left DevSecOps and security teams in a quandary. While they don’t want to impede development efforts, they are left with no choice but to place the security of serverless applications in someone else’s hands.
To alleviate this issue, there are several serverless security best practices that must be put in place in order to properly secure serverless apps launched by the developer.
Serverless Security Best Practices
Don’t rely solely on WAF protection: Application layer firewalls are only capable of inspecting HTTP(s) traffic. This means that a WAF will only protect functions which are API Gateway-triggered functions. It will not provide protection against any other event trigger types. A WAF will not help if your functions are triggered from different events sources, such as:
- Cloud storage events (e.g. AWS S3, Azure Blob storage, Google Cloud 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)
Having a WAF in place is still important, but it is not and should not be the only line of defense in securing serverless applications. Relying solely on a WAF leaves many gaping security holes.
Customize Function Permissions: 90% of permissions in serverless applications are found to be over permissioned. While setting up permissions feels like a daunting task when thinking of the function levels in serverless, a one size fits all approach is not a solution. Setting policies that are larger and more permissive in the function is a common serverless security mistake, and failing to minimize individual function roles and permissions makes your attack surface larger than necessary. Creating proper function level permissions requires DevSecOps teams to sit down with the developers who wrote the functions and review what each function does. Only after determining what each function actually needs to do, can a unique role for each function and a suitable permission policy be created. Luckily there are tools available to help automate this process for heightened AWS Lambda security, as well as other cloud-native platforms.
Conduct a Code Audit: Black Duck Software conducted an audit of 1,000 commonly-used applications in enterprises and found that 96% utilized open-source software. Furthermore, their researchers found that 60% of that software contained security vulnerabilities, and some of the bugs were more than four years old. This makes code ownership and authenticity a critical security risk, as can you really trust what isn’t yours?
Referred 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 of many modules and libraries. The modules often include many other modules, so it’s not uncommon for a single serverless function to include tens of thousands of lines of code from various external sources, even with less than 100 lines of code your developers wrote. Attackers look to include their malicious code in common projects. After poisoning the well, they patiently wait as the new version makes its way into your cloud applications. To enhance AWS serverless security, as well as Microsoft Azure, Google Cloud Functions, etc, it is important to conduct a security audit of the code or look for tooling that can automate the process, scanning for vulnerabilities as a serverless security best practice.
Retain Control Over Your Functions: This may sound like a utopian dream, but code vulnerability can be mitigated through careful CI/CD. Malicious functions can slip in through a variety of means, such as being deployed by a rogue employee. Additionally, develop workstations could be a target for attackers, rather than the deployed apps themselves, and would enable attackers to deploy malicious functions through legitimate channels. Such functions could sneak in and wreak havoc, undetected. To offset this chance, create a policy and strategy for conducting a code analysis during build before it goes into runtime, and make sure every function goes through CI/CD.
Look at All Attack Indicators: Visibility gets harder with serverless. The shift to serverless significantly increases the total amount of information and the number of resources, which hinders DevSecOps and Security team’s ability to make sense of all the data. As the quantity of functions increases, it becomes even more difficult to determine if everything is behaving the way it’s supposed to. Case in point, only a few hundred functions can generate billions of events in your log every day and it becomes difficult to know which are important. Even if you are familiar with the attack patterns that are unique to serverless apps, visually scanning them all simply can’t be done, so leverage AI tools for added serverless security visibility and efficiency.
Time Out Your Functions: 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. DevSecOps teams must consider the configured timeout versus the actual timeout. Many developers set the timeout to the maximum allowed since the unused time doesn’t create an additional expense. However, this approach creates an enormous security risk because 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, but it makes the attack more visible. As a serverless security best practice, shrink not just what a function can do, but how long it can run.
In conclusion, despite new security challenges arising, serverless deployments are great for organizations of all sizes- providing developers with speed to launch, and improving operational costs and efficiencies. Serverless also creates an opportunity to adopt an even greater security posture since everything is at the function level making it even more difficult for attackers. To embrace this new opportunity, it is important for teams to change their approach to application security in serverless deployments. Securing serverless apps requires a variety of tools and tactics, including collaboration between the people involved in the application and the security.