Encryption at rest has long been a cornerstone in data security and it’s something that everyone should take seriously. If an attacker is able to get a hold of your data, encryption at rest becomes your last line of defence.
For instance, in the recent LastPass security breach, the attacker was able to steal customers’ vault data after compromising one of LastPass’s employees’ cloud accounts. The only saving grace from this terrible situation was that the data was encrypted at rest using 256-bit AES.
There have been speculations that the attacker might have been able to break through the encryption and access the unencrypted data for some customers. Perhaps, through a combination of brute force and customers using weak or previously compromised passwords for their vault.
But, nonetheless, without encryption at rest, the situation would have been a lot worse and could have spelt the end of one of the more popular password managers out there.
S3 now encrypts new objects by default
S3 has long supported server-side encryption and as of Jan 5th 2023, it would encrypt any new objects you store by default using SSE-S3. See this launch blog post for more details.
The best thing about this update is that you don’t have to change your application at all. Existing S3 buckets with encryption enabled will not change. But any unencrypted buckets will now use the SSE-S3 encryption automatically.
This is a great update. But it doesn’t mean you don’t have to ever think about S3 encryption again.
You should still use SSE-KMS with a CMK
Having encryption at rest with SSE-S3 means if AWS is compromised and an attacker is able to get to your data, at least they are encrypted.
What if AWS didn’t mess up, but you did?
For example, what if your AWS credentials are compromised (e.g. you accidentally checked them into a public repo!), or you accidentally left a bucket public?
Any request through the AWS SDK, AWS CLI or via the public URL of an object would give the attacker access to the unencrypted object contents. S3 would decrypt the data and return the unencrypted data because it owns the encryption keys.
So what can you do?
The simple answer is to use SSE-KMS with a KMS CMK (Customer Managed Key). With this encryption mode, you tell S3 to encrypt the objects with a KMS key that you control. Anyone who wishes to access the unencrypted content must have the
kms:decrypt permission for the CMK.
Even if a bucket is accidentally left public, this would still protect you from unauthorized access. Attempts to access the objects via their public URL would be met with a swift unauthorized response.
You will need to manage access to this KMS CMK. In production, none of your IAM users and roles your employees would assume should have direct access to it. Only Lambda functions that need to access the data should have decrypt permission.
Follow the principle of least privilege.
The recent S3 update is great and deserves all the excitement and praise that it received. But keep in mind that it adds a baseline level of security to data stored in S3.
It provides a valuable layer of defence against compromises to AWS’s own infrastructure. But it doesn’t protect you from many attack vectors that affect the security of your AWS environment.
Having this baseline security is great, but it’s not enough to safeguard your customers’ data. So no, your job is not done yet!