Description
Ensure that the default cache behavior of every Amazon CloudFront distribution has a field-level encryption configuration associated with it. Field-level encryption lets CloudFront encrypt specific fields of HTTPS POST requests at the edge with a public key, so that only the application holding the matching private key can decrypt them.
Rationale
Without field-level encryption, sensitive form fields such as personal data, payment card numbers or credentials pass in plain text through the origin servers, logs and intermediate services once HTTPS is terminated. This increases the risk of data exposure, insider misuse and credential theft. Encrypting sensitive fields at the edge keeps them protected through the application stack, with decryption keys restricted to the components that need them.
Impact
Keeps selected sensitive fields encrypted from the edge until they reach the component that holds the private key
Limits the exposure of sensitive data in origin servers, logs and intermediate services
The application must be changed to decrypt the fields with the private key, so this requires development work and key management
Field-level encryption only applies to HTTPS POST requests with the configured content types; it has no effect on distributions that only serve static content
Default Value
CloudFront distributions have no field-level encryption configuration associated with their cache behaviors by default.
Pre-Requisites
IAM permissions: cloudfront:GetDistributionConfig, cloudfront:UpdateDistribution, cloudfront:CreatePublicKey, cloudfront:CreateFieldLevelEncryptionProfile and cloudfront:CreateFieldLevelEncryptionConfig
An RSA 2048-bit key pair, with the private key stored securely for the application that will decrypt the fields
The list of request fields to encrypt, agreed with the application owner
The default cache behavior must use the viewer protocol policy Redirect HTTP to HTTPS or HTTPS only, and the origin must be reached over HTTPS
Remediation
Test Plan
Console:
Sign in to the AWS Management Console at https://console.aws.amazon.com.
Open the CloudFront console and select Distributions.
Select a distribution and open the Behaviors tab.
Select the **Default (*) behavior, choose Edit and check the Field-level encryption** setting.
Repeat for each distribution.
If no field-level encryption configuration is selected for the default behavior, follow the implementation steps.
CLI:
Show the field-level encryption configuration of the default cache behavior:
aws cloudfront get-distribution-config --id <DISTRIBUTION_ID> --query "DistributionConfig.DefaultCacheBehavior.FieldLevelEncryptionId"
A distribution fails if FieldLevelEncryptionId is empty. Only the default cache behavior is evaluated.
Implementation Steps
Console:
Sign in to the AWS Management Console at https://console.aws.amazon.com.
Open the CloudFront console and select Public keys in the left menu. Choose Create public key, paste the RSA public key and choose Create public key.
Select Field-level encryption in the left menu and create a profile: select the public key, enter a provider name and the field name patterns to encrypt.
In Field-level encryption, create a configuration: add a content type profile for application/x-www-form-urlencoded that uses the profile from step 3.
Select Distributions, select the distribution and open the Behaviors tab.
Select the **Default (*) behavior and choose Edit**.
Set Field-level encryption to the configuration from step 4 and choose Save changes.
Wait until the distribution status is Deployed, then update the application to decrypt the fields with the private key.
Repeat for each distribution.
CLI:
Run each command separately: update-distribution accepts only the inner DistributionConfig object together with the current ETag, not the full get-distribution-config output.
Save the following as public-key.json, with your PEM-encoded public key:
{"CallerReference":"<UNIQUE_REFERENCE>","Name":"<KEY_NAME>","EncodedKey":"<PEM_PUBLIC_KEY>","Comment":"Field-level encryption key"}
Create the public key and note its Id:
aws cloudfront create-public-key --public-key-config file://public-key.json
Save the following as fle-profile.json:
{"Name":"<PROFILE_NAME>","CallerReference":"<UNIQUE_REFERENCE>","Comment":"","EncryptionEntities":{"Quantity":1,"Items":[{"PublicKeyId":"<PUBLIC_KEY_ID>","ProviderId":"<PROVIDER_NAME>","FieldPatterns":{"Quantity":1,"Items":["<FIELD_NAME>"]}}]}}
Create the field-level encryption profile and note its Id:
aws cloudfront create-field-level-encryption-profile --field-level-encryption-profile-config file://fle-profile.json
Save the following as fle-config.json:
{"CallerReference":"<UNIQUE_REFERENCE>","Comment":"","ContentTypeProfileConfig":{"ForwardWhenContentTypeIsUnknown":true,"ContentTypeProfiles":{"Quantity":1,"Items":[{"Format":"URLEncoded","ProfileId":"<PROFILE_ID>","ContentType":"application/x-www-form-urlencoded"}]}}}
Create the field-level encryption configuration and note its Id:
aws cloudfront create-field-level-encryption-config --field-level-encryption-config file://fle-config.json
Save the distribution configuration and get its current ETag:
aws
cloudfront get-distribution-config --id <DISTRIBUTION_ID>
--query "DistributionConfig" --output json >
dist-config.json
aws cloudfront get-distribution-config --id
<DISTRIBUTION_ID> --query "ETag" --output text
Edit dist-config.json and set DefaultCacheBehavior.FieldLevelEncryptionId to the configuration ID, then apply it with the ETag:
aws cloudfront update-distribution --id <DISTRIBUTION_ID> --distribution-config file://dist-config.json --if-match <ETAG>
Backout Plan
Before making changes, save the current distribution configuration:
aws cloudfront get-distribution-config --id <DISTRIBUTION_ID> --query "DistributionConfig" --output json > dist-config-backup.json
To roll back:
Sign in to the AWS Management Console at https://console.aws.amazon.com.
Open the CloudFront console, select the distribution and open the Behaviors tab.
Select the **Default (*) behavior and choose Edit**.
Clear the Field-level encryption setting and choose Save changes.
CLI:
Get the current ETag with the command used in the implementation steps, then restore the saved configuration:
aws cloudfront update-distribution --id <DISTRIBUTION_ID> --distribution-config file://dist-config-backup.json --if-match <ETAG>
Note: before rolling back, update the application so that it no longer expects encrypted fields. Rolling back exposes the sensitive fields in plain text to the origin again.
Reference