On 29th July 2019 CapitalOne Financial Corp announced a data breach affecting 140 000 of their customer’s social security numbers and 80 000 bank account numbers. CapitalOne is a major user of AWS cloud, and in this case the stolen data was stored in AWS S3 buckets. Since the perpetrator was arrested and left quite a long trail on social media, much more detail about this breach has become public than usual, allowing in-depth analysis of what went wrong.
Why didn’t encryption save us?
Configuring firewalls, IAM roles, VPCs and so on is complicated. It’s not surprising that this occasionally leaves a hole. To protect against such eventualities most corporations require that all sensitive data stored in the cloud is encrypted.
In the CapitalOne statement, they assert:
We encrypt our data as a standard. Due to the particular circumstances of this incident, the unauthorized access also enabled the decrypting of data.
So what is this encryption that doesn’t protect you from a breach?
Tick the box to comply
One possible explanation is that, in this case, server-side encryption was used. This is the easiest way to comply with a requirement that cloud-stored data be encrypted: you just have to select an option in the AWS dashboard and AWS will generate a key, encrypt your data, and store the key for you. When you request the data back, AWS will transparently fetch the key, decrypt the data, and send it to you. This is not just an AWS feature, all major CSPs offer this functionality (in GCP it happens automatically).
This might protect you from some hypothetical insider at AWS who gets access to the raw data of your S3 bucket, but it doesn’t protect you from the far more likely attack that happened to CapitalOne: a server-side request forgery or SSRF, where the attacker persuades the application to make a request under his own control.
AWS (and other CSPs) offer an extra level of control on server-side encryption, where you can specify a particular key in their key-management service (KMS) that will wrap the data key for the S3 bucket. To decrypt, you will need IAM permission to access the KMS as well as access the bucket. In the CapitalOne case, if this extra feature was in use, it seems like the same credentials allowed access to both.
To address the shortcomings of server-side encryption you need to use what’s called client side encryption, where the encryption key is managed by your own application, setting the bar far higher for a successful SSRF attack.
The trouble is, client-side encryption is more complicated, imposing key-management responsibilities, requiring parameter choices that may have unintended consequences (see our recent article on AWS S3 Client-side encryption), and requiring a control at the application level to be sure its being used correctly.
Making client-side encryption easy
In the next few blog posts, to complete the series we started with AWS S3, we’ll be looking at how client-side encryption works in the other two of the big 3 CSP’s block storage services (Azure and GCP). We’ll also discuss how you can control at scale that all your cloud applications are following your client-side encryption policy using Cryptosense Analyzer Platform. To make sure you don’t miss anything, subscribe to this blog or follow us on twitter.