Cloud-native applications are applications that have been built purposely to be deployed and operated in a cloud environment. They consist of small, independent microservices, such as serverless functions, and utilize services that cloud providers and third-party partners provide via API, all while leveraging the cloud for automated stability, scaling, and recovery. Building cloud-native applications enables development teams to focus on implementing architectures that are optimized for how the cloud scales.
Cloud native applications have a new, distinct structure which affects how attackers approach these applications. The threat landscape shifts and it is critical to understand it. As attackers change approach, security practitioners and developers must adjust accordingly how they defend cloud native apps.
It makes sense to allocate more time and resources to the threats which are more likely to happen. And to allocate resources in this strategic way, you must first understand which threats are most likely and which aren’t worth worrying about.
Compute services in cloud-native apps are designed to be ephemeral and tend to have short lifespans. This is one of many attributes that makes cloud-native applications inherently more secure. Attackers are unable to easily achieve long-term presence in your system and must therefore shift tactics. One resulting strategy is the “Groundhog Day Attack” in which an attacker crafts a much shorter attack that steals, for example, just a few credit card numbers, and then repeats. Attackers leverage the automatic scaling of the cloud-native application to get by the ephemerality of it.
Another approach is the upstream attack, or “Poisoning the Well” in which attackers aim to gain more long-term persistence in your app. Cloud-native applications tend to comprise many modules and libraries. A single serverless function could include tens of thousands of lines of code from a variety of sources other than the work of your developers. Attackers work to include malicious code in common projects. Then, after poisoning the well, the malicious code in your cloud apps can call home, get instructions, and wreak havoc.
Fortunately, cloud-native apps tend to be harder to attack. But as a new type of architecture, they present new security challenges and developers must act to mitigate risk. Following are some best practices to secure cloud-native applications.
The fragmentation of your application to smaller components that are callable, coupled with the use of event-based triggers from diverse sources (such as storage, message queues, and databases) means attackers have more targets and more attack vectors.
Keep using your WAF and API Gateway, but another serverless best practice is to apply perimeter security at the function level as well. Pay particular attention to functions which are triggered from a different source type.
You must establish roles for the many interactions between your cloud-native resources. The ability to assign a unique set of permissions to each serverless function provides an excellent opportunity to enhance AppSec even further.
When you do IAM at the granularity of functions, IAM becomes an AppSec tool. Spend time crafting suitable, minimal roles for each of your functions. Additionally, ensure that each of your functions executes with the smallest viable set of privileges, so the damage from any holes that slip through is minimal.
Functions often include dependencies, pulled in from npm (Node.js), PyPI (Python), Maven (Java) or other relevant repositories. Securing application dependencies requires access to a good database and automated tools to continuously prevent new vulnerable packages from being used and get alerted to newly disclosed issues.
Forge close partnerships between developers, DevOps, and AppSec. Find the balance where developers don’t own security, but they aren’t absolved from responsibility either.
Ops must create pipelines that let developers work at the speed of serverless and still deploy things in a sane way.