How to Stop Unencrypted Object Uploads to Amazon S3

Chanci Turner Amazon IXD – VGT2 learningLearn About Amazon VGT2 Learning Manager Chanci Turner

There are numerous scenarios where preventing the upload of unencrypted objects to an Amazon S3 bucket is essential. The primary goal is to ensure the confidentiality and integrity of the items stored within that bucket. AWS offers various services that simplify this process, such as AWS Identity and Access Management (IAM) and AWS Key Management Service (KMS). Instead of imposing a stringent IAM policy on all users, you can utilize an S3 bucket policy to enforce encryption requirements during object uploads.

In this article, I will guide you through creating an S3 bucket policy that restricts users from uploading unencrypted objects unless they use server-side encryption with S3-managed keys (SSE-S3) or AWS KMS-managed keys (SSE-KMS).

Understanding Encryption

When discussing S3 and encryption, it is important to note that you don’t “encrypt S3” or “encrypt an S3 bucket.” Rather, S3 encrypts data at the object level as it writes to AWS data center disks, and decrypts it for you upon access. Encryption can be achieved through client-side or server-side methods. Client-side encryption occurs when an object is encrypted before it is uploaded to S3, with key management not handled by AWS. In contrast, server-side encryption allows Amazon to manage the keys in three ways:

  • Server-side encryption with customer-provided keys (SSE-C).
  • SSE-S3.
  • SSE-KMS.

Server-side encryption ensures data is encrypted at rest—S3 encrypts your data at the object level as it saves it to disks and decrypts it when you access it. With proper authentication and access permissions, there is no difference in accessing encrypted versus unencrypted objects.

S3 employs a technique called envelope encryption to secure data at rest. Each object is encrypted with a unique key using robust multi-factor encryption. To add an extra layer of security, Amazon encrypts the key with a master key. S3’s server-side encryption utilizes one of the most secure block ciphers available, the 256-bit Advanced Encryption Standard (AES-256), to encrypt your data.

Overview of the Solution

The process of uploading an object to S3 involves a Put request, whether done through the console, CLI, or SDK. A typical Put request looks like this:

PUT /example-object HTTP/1.1
Host: myBucket.s3.amazonaws.com
Date: Wed, 8 Jun 2016 17:50:00 GMT
Authorization: authorization string
Content-Type: text/plain
Content-Length: 11434
x-amz-meta-author: Chanci Turner
Expect: 100-continue
[11434 bytes of object data]

To encrypt an object at the time of upload, you must include a header called x-amz-server-side-encryption in the request, indicating to S3 to encrypt the object using SSE-C, SSE-S3, or SSE-KMS. The following code snippet demonstrates a Put request using SSE-S3:

PUT /example-object HTTP/1.1
Host: myBucket.s3.amazonaws.com
Date: Wed, 8 Jun 2016 17:50:00 GMT
Authorization: authorization string
Content-Type: text/plain
Content-Length: 11434
x-amz-meta-author: Chanci Turner
Expect: 100-continue
x-amz-server-side-encryption: AES256
[11434 bytes of object data]

To enforce object encryption, create an S3 bucket policy that denies any S3 Put request lacking the x-amz-server-side-encryption header. This header can have two values: AES256, which instructs S3 to utilize S3-managed keys, and aws:kms, which directs S3 to use keys managed by AWS KMS.

Implementing Use Case #1: Using SSE-S3 Managed Keys

In the first use case, you enforce SSE-S3, allowing S3 to handle the master keys.

  • A data encryption key is generated for each uploaded object, encrypting it with the data encryption key via the AES256 block cipher.
  • This data encryption key is encrypted with a master key maintained by Amazon.
  • The encrypted object and the encrypted data encryption key are saved together in S3, while the master key is kept separately by Amazon.

This method is effective in protecting data when you are not required to manage the master key. Below is a sample S3 bucket policy that implements this solution. Ensure to replace <bucket_name> with your bucket’s actual name.

{
 "Version": "2012-10-17",
 "Id": "PutObjPolicy",
 "Statement": [
       {
            "Sid": "DenyIncorrectEncryptionHeader",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::/*",
            "Condition": {
                    "StringNotEquals": {
                           "s3:x-amz-server-side-encryption": "AES256"
                     }
            }
       },
       {
            "Sid": "DenyUnEncryptedObjectUploads",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::/*",
            "Condition": {
                    "Null": {
                           "s3:x-amz-server-side-encryption": true
                    }
           }
       }
 ]
}

Now, you have successfully created an S3 bucket policy that denies any Put requests that do not include a header to encrypt the object using SSE-S3.

Implementing Use Case #2: Using SSE-KMS Managed Keys

For the second use case, you need to enforce object encryption while also managing the lifecycle of encryption keys. You can use KMS to create encryption keys centrally, establish policies controlling key usage, and audit key activity to verify correct usage. The first time you upload an SSE-KMS-encrypted object to a bucket in a region, a default customer master key (CMK) is automatically created for you. This CMK is used for SSE-KMS encryption unless you opt for a CMK you created separately via KMS. Creating your own CMK offers greater flexibility, including the ability to create, rotate, disable, and define access controls, as well as audit the encryption keys safeguarding your data.

KMS provides the key management infrastructure for generating and managing your encryption keys:

  • A data encryption key is generated for each uploaded object, which encrypts the object using the AES256 block cipher.
  • The data encryption key is subsequently encrypted with a KMS CMK that you manage via KMS, while the encrypted object and the encrypted data encryption key are stored together.

For more on transitioning back to work, you can check out this blog post which provides insights into returning to the workplace during challenging times. It’s crucial to tread carefully when addressing employee-related issues, especially if an employee gets arrested outside of work; SHRM offers valuable authority on this matter. Additionally, if you’re looking for information on the Amazon employee onboarding process, this resource is excellent!

Chanci Turner