Cloudfront Fieldlevel Encryption Remediation
Triage and Remediation
- Remediation
Remediation
Using Console
To remediate the misconfiguration "CloudFront Distributions Should Have Field-Level Encryption Enabled" in AWS using AWS console, follow the below steps:
- Login to AWS Management Console.
- Go to the CloudFront service.
- Select the CloudFront distribution for which you want to enable field-level encryption.
- Click on the "Edit" button in the top menu.
- Scroll down to the "Security and Privacy" section.
- In the "Field-level Encryption Config" section, click on the "Create Field-level Encryption Config" button.
- In the "Create Field-level Encryption Config" dialog box, enter a name for the configuration and click on the "Create" button.
- In the "Field-level Encryption Config" section, select the newly created configuration from the dropdown list.
- Click on the "Yes, Edit" button to save the changes.
- Finally, click on the "Save Changes" button to complete the remediation.
By following these steps, you have successfully enabled Field-level Encryption for the selected CloudFront distribution in AWS.
Using CLI
To remediate the misconfiguration of CloudFront distributions not having field-level encryption enabled in AWS using AWS CLI, follow these steps:
- Open the AWS CLI on your local machine and run the following command to enable field-level encryption for your CloudFront distribution:
aws cloudfront update-distribution --id DISTRIBUTION_ID --field-level-encryption-config Id=FIELD_LEVEL_ENCRYPTION_ID,ForwardWhenContentTypeIsUnknown=true
Replace DISTRIBUTION_ID with the ID of your CloudFront distribution and FIELD_LEVEL_ENCRYPTION_ID with the ID of the field-level encryption configuration that you want to use.
- Verify that field-level encryption is enabled for your CloudFront distribution by running the following command:
aws cloudfront get-distribution-config --id DISTRIBUTION_ID
This command will return the current configuration for your CloudFront distribution. Verify that the FieldLevelEncryptionId parameter is set to the ID of the field-level encryption configuration that you specified in step 1.
- Test your CloudFront distribution to ensure that field-level encryption is working as expected.
Congratulations! You have now successfully remediated the misconfiguration of CloudFront distributions not having field-level encryption enabled in AWS using AWS CLI.
Using Python
To remediate the misconfiguration "CloudFront Distributions Should Have Field-Level Encryption Enabled" in AWS using Python, you can follow the below steps:
- Import the Boto3 library:
import boto3
- Create a CloudFront client object:
client = boto3.client('cloudfront')
- Get the list of CloudFront distributions:
response = client.list_distributions()
- Loop through each distribution and check if field-level encryption is enabled:
for distribution in response['DistributionList']['Items']:
distribution_id = distribution['Id']
response = client.get_distribution_config(Id=distribution_id)
if 'FieldLevelEncryption' not in response['DistributionConfig']:
# Field-level encryption is not enabled, remediate it
- If field-level encryption is not enabled, enable it by adding a field-level encryption configuration:
field_level_encryption_config = {
'CallerReference': 'unique_reference_string',
'FieldLevelEncryptionConfig': {
'FieldLevelEncryptionProfileConfig': {
'Name': 'profile_name',
'CallerReference': 'unique_reference_string',
'EncryptionEntities': {
'Quantity': 1,
'Items': [
{
'PublicKeyId': 'public_key_id',
'ProviderId': 'provider_id'
}
]
}
},
'ContentTypeProfileConfig': {
'ForwardWhenContentTypeIsUnknown': False,
'ContentTypeProfiles': {
'Quantity': 1,
'Items': [
{
'Format': 'URLEncoded',
'ProfileId': 'profile_id',
'ContentType': 'content_type'
}
]
}
}
}
}
response = client.update_distribution(
DistributionConfig={
'CallerReference': 'unique_reference_string',
'Aliases': {
'Quantity': 1,
'Items': [
'example.com'
]
},
'DefaultRootObject': 'index.html',
'Origins': {
'Quantity': 1,
'Items': [
{
'Id': 'unique_id',
'DomainName': 'example.com',
'OriginPath': '',
'CustomHeaders': {
'Quantity': 0
},
'S3OriginConfig': {
'OriginAccessIdentity': ''
},
'CustomOriginConfig': {
'HTTPPort': 80,
'HTTPSPort': 443,
'OriginProtocolPolicy': 'https-only',
'OriginSslProtocols': {
'Quantity': 3,
'Items': [
'TLSv1',
'TLSv1.1',
'TLSv1.2'
]
}
}
}
]
},
'DefaultCacheBehavior': {
'TargetOriginId': 'unique_id',
'ForwardedValues': {
'QueryString': False,
'Cookies': {
'Forward': 'none'
},
'Headers': {
'Quantity': 0
},
'QueryStringCacheKeys': {
'Quantity': 0
}
},
'TrustedSigners': {
'Enabled': False,
'Quantity': 0
},
'ViewerProtocolPolicy': 'redirect-to-https',
'MinTTL': 0,
'AllowedMethods': {
'Quantity': 2,
'Items': [
'GET',
'HEAD'
],
'CachedMethods': {
'Quantity': 2,
'Items': [
'GET',
'HEAD'
]
}
},
'SmoothStreaming': False,
'DefaultTTL': 86400,
'MaxTTL': 31536000,
'Compress': False,
'LambdaFunctionAssociations': {
'Quantity': 0
}
},
'CacheBehaviors': {
'Quantity': 0
},
'CustomErrorResponses': {
'Quantity': 0
},
'Comment': '',
'Logging': {
'Enabled': False,
'IncludeCookies': False,
'Bucket': '',
'Prefix': ''
},
'PriceClass': 'PriceClass_All',
'Enabled': True,
'ViewerCertificate': {
'CloudFrontDefaultCertificate': True,
'MinimumProtocolVersion': 'TLSv1',
'CertificateSource': 'cloudfront'
},
'Restrictions': {
'GeoRestriction': {
'RestrictionType': 'none',
'Quantity': 0
}
},
'WebACLId': '',
'HttpVersion': 'http2',
'IsIPV6Enabled': True,
'FieldLevelEncryption': field_level_encryption_config
},
Id=distribution_id,
IfMatch=response['ETag']
)
-
Replace the
unique_reference_string,profile_name,public_key_id,provider_id,profile_id,content_type,example.com,unique_id, andbucket_namewith the appropriate values for your CloudFront distribution. -
Save the Python script and execute it to remediate the "CloudFront Distributions Should Have Field-Level Encryption Enabled" misconfiguration in AWS.
Using Terraform
resource "aws_cloudfront_distribution" "WEB_DISTRIBUTION" {
# existing arguments...
enabled = true
default_root_object = "index.html"
origin {
domain_name = "APP_ORIGIN_DOMAIN_NAME" # e.g. myapp.example.com.s3.amazonaws.com
origin_id = "APP_ORIGIN_ID"
}
default_cache_behavior {
target_origin_id = "APP_ORIGIN_ID"
viewer_protocol_policy = "redirect-to-https"
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
# This is the critical setting to enable field‑level encryption
field_level_encryption_id = aws_cloudfront_field_level_encryption_config.SENSITIVE_FIELDS.id
# ...your other cache behavior settings (forwarded_values, cache_policy_id, etc.)
}
# If you have ordered_cache_behavior blocks that should also use FLE,
# add the same argument to each of them:
#
# ordered_cache_behavior {
# path_pattern = "/payments/*"
# target_origin_id = "APP_ORIGIN_ID"
# viewer_protocol_policy = "redirect-to-https"
# allowed_methods = ["GET", "HEAD", "POST"]
# cached_methods = ["GET", "HEAD"]
#
# field_level_encryption_id = aws_cloudfront_field_level_encryption_config.SENSITIVE_FIELDS.id
#
# # ...other behavior settings...
# }
# ...rest of your distribution config (viewer_certificate, restrictions, etc.)
}
resource "aws_cloudfront_field_level_encryption_config" "SENSITIVE_FIELDS" {
comment = "Field-level encryption config for sensitive fields"
query_arg_profile_config {
forward_when_query_arg_profile_is_unknown = false
query_arg_profiles {
quantity = 1
items {
query_arg = "QUERY_ARG_NAME_TO_ENCRYPT" # e.g. "cardNumber"
profile_id = aws_cloudfront_field_level_encryption_profile.SENSITIVE_PROFILE.id
}
}
}
# If you encrypt headers instead of query args, use headers_config instead:
#
# content_type_profile_config { ... } OR
# - see AWS docs for the exact structure you need
}
resource "aws_cloudfront_field_level_encryption_profile" "SENSITIVE_PROFILE" {
name = "SENSITIVE_PROFILE_NAME"
comment = "Profile for encrypting sensitive fields"
encryption_entities {
quantity = 1
items {
public_key_id = aws_cloudfront_public_key.FLE_PUBLIC_KEY.id
provider_id = "FLE_PROVIDER_ID" # e.g. "ExampleFLEProvider"
field_patterns {
quantity = 1
items = ["FIELD_PATTERN_TO_ENCRYPT"] # e.g. "cardNumber"
}
}
}
}
resource "aws_cloudfront_public_key" "FLE_PUBLIC_KEY" {
name = "FLE_PUBLIC_KEY_NAME"
comment = "Public key for field-level encryption"
encoded_key = file("PATH_TO_PUBLIC_KEY_PEM") # e.g. ./keys/fle_public_key.pem
}
Changing field_level_encryption_id on an existing aws_cloudfront_distribution updates the distribution in place and does not force replacement, though CloudFront will take time to fully deploy the change globally.
To verify, terraform plan should show:
+creation ofaws_cloudfront_public_key.FLE_PUBLIC_KEY+creation ofaws_cloudfront_field_level_encryption_profile.SENSITIVE_PROFILE+creation ofaws_cloudfront_field_level_encryption_config.SENSITIVE_FIELDS~an in-place update toaws_cloudfront_distribution.WEB_DISTRIBUTIONwithfield_level_encryption_idset on the relevant cache behavior(s).