Cloud Security Essentials for startups: Part 1
A low effort high impact guide for securing your infra
I understood the importance of security about 3 years ago when I was running my AI startup and woke up one day to see all our S3 data was gone. Somehow our AWS S3 credentials got leaked and we had not put in place a robust policy to prevent our data in such a scenario. We realized that security is something that should not be taken lightly and started working on it. However, we wanted to ensure that we don’t compromise on development speed and developer productivity due to it, especially in the early phases of our startup, where speed is critical and the only advantage you have over others.
Writing this post to cover some the low hanging fruits what every team can use to ensure safety against attacks. The important point to note is - security is all about layers i.e. how many layers does a malicious actor has to crack to affect your system.
1. IP addresses in AWS keys
A very simple yet effective way to secure your AWS credentials is to specify the IP ranges which can access the AWS services. This does not require any code change as well. More details here - https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_aws_deny-ip.html
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"192.0.2.0/24",
"203.0.113.0/24"
]
},
"Bool": {"aws:ViaAWSService": "false"}
}
}
}
What is helps in is, even if the credentails get leaked, they cannot be used outside the production server. So there are two layers of protection - Credentials and Your server’s SSH keys.
Layers of security - 2 (S3 credentials + Server access)
2. No delete permission
Most of the times, we don’t delete data that is uploaded to S3. What it means is your can have two set of credentials - one with Put/Get permission and other one with delete. Rarely, if ever, we require bucket delete permission. So the idea is here to not use * in Action key, but specify the required permissions. This requires some code changes but since s3 operations are generally done through util functions, this change can be easily done.
Layers of security - 3 (S3 credentials + Server access + No deletion)
3. S3 bucket versioning
A great feature, which ensures that data is not deleted by mistake or by malicious attack.
Versioning-enabled buckets can help you recover objects from accidental deletion or overwrite. For example, if you delete an object, Amazon S3 inserts a delete marker instead of removing the object permanently. The delete marker becomes the current object version. If you overwrite an object, it results in a new object version in the bucket.
Versioning is unfortunately disabled by default and must be enabled in each bucket separately. But once done, it also prevents programmatic deletion of buckets.
Layers of security - 3 (S3 credentials + Server access + Versioning)
3. AWS backup for S3
AWS provides a great functionality to create automated backups for S3.
The AWS Backup vault is a logical container that stores and manages your encrypted backups. When creating a backup vault, you must specify the AWS Key Management Service (AWS KMS) encryption key that encrypts the backups placed in this vault. All copied backups are encrypted with the key of the target vault.
The biggest advantage of AWS backup is, even if your account is compromised, these backups are read only and cannot be deleted even by root user. The only way to delete is to delete the complete account itself.
Layers of security - ∞ ( as you cannot delete these backups)
5. Separate Virtual Network for Production deployments and No direct access
Our development environment is the most exposed and used most frequently. The chances of SSH key of development server being leaked are high. It is best to separate the production deployments on separate Virtual network and accessible only through VPN. This should include queues, databases, cache servers, main application servers etc.
Layers of security - 3 (S3 credentials + Server access + VPN)
6. Database protection
We generally create users with all permissions and no restrictions on IP addresses. In order to add another layer to your database, we can specify IP ranges to users we create. That way, even if credentials get leaked, there is an additional layer of security.
CREATE USER 'david'@'198.51.100.44/24';
More details here - https://dev.mysql.com/doc/mysql-security-excerpt/8.0/en/account-names.html
Layers of security - 3 (DB credentials + Server access + VPN)
7. 2FA for cloud login
While analyzing security layers at different steps, We realized that cloud login is single layer of protection and anyone can login if the password is leaked. This can be dangerous as root login in cloud console has lot of access. The best way is to have separate users for different uses like Databases, Logs, etc and each user must have MFA enabled.
8. Using a Secret manager
We all know that we should not have access keys in our code, that they should not be part of git and that they should be stored in some Vault. AWS Secret Manager or Hashicorp Vault provide easy to use interfaces for the same.
As mentioned earlier, in terms of security, think in layers and keep on adding layers . No system can be 100% secure, but with small efforts we can make it safe from standard hacks. The above points cover some of the aspects but the list is longer. We took other actions to secure our APIs, token and servers further. Will be discussing them in a separate post.
Ending with a quote -
Security is the lowest priority till it becomes the highest.