If you’d like to use serverless technology to build your products, you have many services to choose from—starting with a basic function-as a service offering and up to pre-trained machine-learning models. Saving all that development time and focusing on value delivery is a good thing, but if you glue together a bunch of distributed services, your end product will consist of many moving parts.
Software is never perfect, so every service can become a risk. Additionally, if one of your Lambda functions gets hacked and it can access more information than it should, this can lead to big problems.
In this article, we’ll talk about security best practices for popular AWS services and how Thundra’s blacklists and whitelists can help plug security holes.
AWS Security Best Practices
First, let’s talk about the popular AWS services and what AWS considers security best practices.
Spreading IAM roles and users over multiple accounts will get cumbersome rather quickly, so use a central AWS account for all IAM users and roles to see at one glance who has access to what.
Also, using IAM groups for cross-account permissions eliminates the need to modify permissions for IAM roles and users directly. To give them access to the infrastructure of a different AWS account, just add them to a new group.
To get a sense of what is accessed and when, activate CloudTrail logs. CloudTrail is a service that logs all activity on your AWS infrastructure, whether the actions have been issued via the AWS Console, AWS SDK, or command-line tools.
As your infrastructure grows, it can also be handy to let CloudTrail create tables for Amazon Athena, the AWS interactive query service, to enable you to search through the logged account activities more easily. You can read an article on linking CloudTrail with Athena here.
S3, the AWS object storage service, can be a floodgate for unauthorized access if configured improperly. To prevent this, set all your buckets to “private,” “server access logs,” and “s3 object-level logs.” This blocks outside access and lets you keep constant track of what’s happening with your data in S3.
If external access is needed, try to use signed URLs and CloudFront Origin Identities. To get a more detailed explanation, look at the AWS docs here. Using CloudFront to distribute assets stored in S3 can often be cheaper and faster than making an S3 bucket publicly available directly via HTTP.
AWS Lambda is a general compute service and as such, can theoretically do everything within your infrastructure. With this in mind, it should be obvious that it’s extremely important to keep the number of Lambda function permissions as low as possible.
AWS recommends applying the principle of “least privilege” for IAM roles. This is an important principle of computer security, which you can read more about here.
Sometimes things can get a bit hazy here, especially when you’re using third-party libraries that don’t state clearly what permissions they need. In this case, Thundra’s blacklist and whitelist feature, which we’ll talk more about later, can help.
Another best practice is to store API keys encrypted and load them into the Lambda function at runtime. This way they aren’t stored in plain text, which means that even if an attacker finds them, he won’t be able to use them. AWS Secrets Manager, which offers an API to load and decrypt stored keys whenever they’re needed, is a useful tool.
API Gateway is your serverless system’s door to the world, so it’s best to get a good lock for it. In serverless security terms, this means adding an authorizer to your API Gateway-based APIs.
To integrate with existing setups, a custom authorizer based on a Lambda function is the tool of choice. When a client sends a request to an API Gateway endpoint, you can intercept it with a Lambda function that handles the authorization process. In the simplest case, this can mean just transforming the credentials and piping them to your existing auth server.
When you’re starting a new project, Cognito, the AWS service for serverless authentication and authorization, can be a quick and simple way to get user management up and running. Cognito comes with user pools to manage accounts and federated authentication for integration with social login providers like Facebook or GitHub, but also SAML-based enterprise auth systems. If you don’t want to run your own user management system, these AWS docs can help you get started with Cognito and REST.
If you’re already using Cognito user pools and are looking for granular access control via IAM, this article is for you.
DynamoDB is the AWS database for the serverless age. If you want to store your data there, you still have to follow some rules to keep it secure.
First, as mentioned in our discussion of Lambda, it’s important to follow the least privilege principle with all the IAM roles that will access your DynamoDB tables. Don’t give a Lambda function full DynamoDB access just because it’s convenient.
Furthermore, to prevent users from reading data they are not allowed to read, filter all queries with user-specific data from JWTs. The content of a JWT is cryptographically signed, so a user can’t change it. If you use a user ID from a JWT, you can be sure that you were the one who put it into the token. If you filter a document list by a user ID, every item that doesn’t belong to that user will be skipped before the result is sent back to the client.
Thundra Security Features
AWS offers a lot in terms of security, and if you follow the best practices mentioned above you are usually good to go. Sometimes, though, configuration of a service can get a bit messy, especially when you’re using third-party libraries inside your Lambda functions.
Among the questions you’ll need to consider are, which service does the library access? What permissions does the library need?
Thundra offers a solution in the form of blacklists and whitelists.
Blacklists prevent access to resources you’ve added to the list and in turn, allow access to all other resources. You can use blacklists to prevent access to specific services for a Lambda function.
For example, if you find out that a third-party library accesses a service with corrupted security, you can quickly add that service to a blacklist and prevent all access to it.
A whitelist allows access to resources added to it, and in turn, prevents access to all other resources.
Whitelists can be useful in many ways. For example, you can configure them to notify you when a Lambda function tries to access something that isn’t whitelisted. If you aren’t sure what a third-party library is doing, a whitelist is a good way to get a picture of the library’s access patterns. It’s also possible to block the access instantly to ensure that no data will be exposed. You’ll still get a notification when an attempt is made.
Thundra whitelists can be automatically generated from your Lambda function’s access data that Thundra has already logged. For example, in the image below you can see that the Lambda function’s existing connections are whitelisted, and Thundra lets you add new whitelisted resources as well.
Figure 1: Thundra console security configuration
AWS Security Best Practices: Knowledge That’s Essential
When you start your first project with serverless technology on AWS, whether greenfield or brownfield, it’s important to familiarize yourself with AWS security best practices and really understand them. Cloud providers help you minimize staffing requirements to run huge services, but they can’t handle security alone.
The principle of least privilege is a crucial concept in computer security and should be applied whenever possible. With IAM, AWS offers a very granular way to implement this concept in your serverless systems, so use it wisely.
If things are not entirely clear when you’re using third-party libraries and frameworks, Thundra’s blacklists and whitelists can help you get a clear picture of what’s happening in the cloud. This will help you stay on top of things when you’re relying on external services that have been compromised.