One of the benefits of Serverless architectures, and AWS Lambda specifically, is that there is #NoOps required to get your code live. You provide the code and deployment, patching and hardware are abstracted away from you.
The issue is, there is still a server. Hot lambda invocations (invoking the function while the cloud provider has your runtime and code provisioned) can allow information leaking across lambda invocations, networks are still a thing, underlying operating systems change and you’re adding code dependencies.
From experience on several serverless projects, this is a checklist of security concerns to look out for on Serverless projects.
When the temporary is persistent
The /tmp directory is the only place you can write to disk on a Lambda function invocation. It’s useful to persist connections and optimize caching, but it does break the sandboxing concept of Lambda.
Issues can arise if any application data, meta-data or logs can be accessed by your (or injected) code. The best practice is to, like your parents always told you, cleanup after yourself.
Always remove any file written to the /tmp directory unless you are explicitly doing it to optimize performance and have considered all potential security risks.
Separation of Lambda Concerns
Separation of concerns is always a good way to win an architectural debate, and it’s sound advice. One of the advantages of running code in a cloud environment like AWS is the ability to lock down permissions based on roles. In AWS, IAM policies allow fine-grained permissions over resources.
If you’re building a large monolithic application in a container environment, policies don't help you as much as they could. If, on the other hand, you’re in a serverless environment and have broken down your application into fine-grained “micro-lambdas” that do one thing and do it well, then you can apply fine-grained policies that prevent your code (or third party code) accessing resources they shouldn’t.
Keep your Lambdas fine grained with a separation of concerns.
Don’t go wild with IAM
As discussed above, IAM is a powerful tool to lock down security. Serverless development is massively empowering to the development team in part because it allows them to work independently of a dedicated ops team. Spinning up new environments and microservices is easy. The risk is that badly configured IAM policies can leave lambdas open to doing things their (or third party) code should not be doing.
If we have the ability to send an email, should all lambdas in the project be able to send emails? Or run a machine learning model? Or access an RDS instance? Or call another Lambda?
Ensuring your IAM policies give the least privilege possible to perform a specific task will reduce the risk of it doing things it’s not supposed to be doing and mitigate the impact of such attacks. The simple version of this is preventing wildcards in roles and policies, but a more advanced version can be achieved. Cloudformation linters on generated cloudformation, a basic grep or Serverless Enterprise Safeguards can provide automated protection from basic over-privileging as part of your CI pipeline. On top of this training, code review and policy audits can provide a further quality assurance.
Ensure all IAM policies allow the least privileges needed to perform their task. Train your team on this principle and ensure basic checks are enforced on CI.
Gateway to Heaven
Don’t expose Lambda functions to the wider Internet unless strictly needed. If they are exposed, do not expose them for direct invocation, but put them behind an API Gateway.
API Gateways provide DDOS protection, rate limiting and simple integration with “Authentication as a Service” providers like Cognito or Okta.
Avoid exposing Lambda functions to the Internet and if exposed only allow invocation through API Gateway.
Know what’s happening
Logging is nothing new, but the flexibility, granularity and distributed nature of serverless architectures make observability more challenging. CloudWatch logging is the basic requirement, adding X-Ray is a must if lambda functions are chained or events are going through multiple services.
Taking this a step further, logging is something to consider when designing your architecture. Splitting functions so that logging is clear and recoverable can become key as your architecture and request load scales.
Basic logging is a given. Add onto this, X-Ray Logging and specialised third-party Serverless logging providers.
Don’t forget the basics
On the whole serverless changes a lot about how you build applications, but the fundamentals of security do not change. You still need to follow best practices when it comes to application code, access control and encryption…
Keep applying basic security principles and use the OWASP Top Ten as your reference.
Serverless architectures reduce a lot of the ops and patching work needed to ensure security and availability. That said, they also introduce new attack vectors that are not as well known, simplicity lets you get away without knowing how the underlying machine is working and security basics don’t go away.
The above principles are based on our team’s experience across serverless projects. Any comments, queries, and additions are more than welcome.