Insecure encryption algorithm - Default encryption
Need
Implementation of Customer Controlled Keys (CMK) for encryption
Context
- Usage of Ruby for building dynamic and object-oriented applications
- Usage of aws-sdk for interacting with Amazon Web Services (AWS) services
Description
Non compliant code
require 'aws-sdk'
s3 = Aws::S3::Client.new(
region: 'us-west-2',
access_key_id: 'AKIAIOSFODNN7EXAMPLE',
secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
)
# Create a new S3 bucket with default key
s3.create_bucket({
bucket: 'mybucket',
create_bucket_configuration: {
location_constraint: 'us-west-2'
}
})
# Upload a file to the new S3 bucket using default key
File.open('myfile.txt', 'rb') do |file|
s3.put_object({
bucket: 'mybucket',
key: 'myfile.txt',
body: file
})
end
In the above Ruby code snippet, we are using the AWS SDK to interact with Amazon S3 service. We are creating a new bucket and uploading a file to this bucket. However, the issue here is that we are using the default encryption key provided by AWS for our S3 bucket.
The potential vulnerability lies in the fact that the default encryption keys are managed by AWS, which means we don't have full control over them. If the default keys were to be compromised, our data could be at risk.
In this scenario, it's better to use Customer Managed Keys (CMKs) with AWS Key Management Service (KMS). CMKs give us more control over the cryptographic keys and we can establish and enforce our own key management policies.
Steps
- Use a secure encryption algorithm instead of the default encryption algorithm provided by AWS SDK.
- Generate and use a Customer Master Key (CMK) for encryption.
- Configure the AWS SDK to use the CMK for encryption.
- Update the code to create the S3 bucket and upload files using the CMK for encryption.
Compliant code
require 'aws-sdk'
kms = Aws::KMS::Client.new(
region: 'us-west-2',
access_key_id: 'AKIAIOSFODNN7EXAMPLE',
secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
)
# Create a new CMK
cmk = kms.create_key({
description: 'My CMK',
key_usage: 'ENCRYPT_DECRYPT',
origin: 'AWS_KMS'
})
s3 = Aws::S3::Client.new(
region: 'us-west-2',
access_key_id: 'AKIAIOSFODNN7EXAMPLE',
secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
)
# Create a new S3 bucket with CMK
s3.create_bucket({
bucket: 'mybucket',
create_bucket_configuration: {
location_constraint: 'us-west-2'
}
})
# Upload a file to the new S3 bucket using CMK
File.open('myfile.txt', 'rb') do |file|
s3.put_object({
bucket: 'mybucket',
key: 'myfile.txt',
body: file,
server_side_encryption: 'aws:kms',
ssekms_key_id: cmk.key_metadata.key_id
})
end
The above code first creates a new Customer Master Key (CMK) using the AWS Key Management Service (KMS). This CMK is then used to encrypt the data stored in the S3 bucket.
The create_key
method is used to create a new CMK. The description
parameter is used to provide a description for the CMK. The key_usage
parameter is set to 'ENCRYPT_DECRYPT' to allow the CMK to be used for both encryption and decryption. The origin
parameter is set to 'AWS_KMS' to specify that the CMK is created within AWS KMS.
The put_object
method is used to upload a file to the S3 bucket. The server_side_encryption
parameter is set to 'aws:kms' to specify that AWS KMS is used for server-side encryption. The ssekms_key_id
parameter is set to the ID of the CMK to specify that the CMK is used for encryption.
This way, the data stored in the S3 bucket is encrypted using a secure encryption algorithm provided by the CMK, instead of the default encryption algorithm provided by the AWS SDK.