Amazon CloudFront and Amazon Route 53 sit in front of everything else in an AWS estate, so a misconfigured origin, a forgotten signing key or a stale DNS record exposes content and brand to anyone who notices first. CloudFront decides who can reach your origins and on what terms; Route 53 decides where your names point and whether those answers can be trusted. This guide covers the customer-side settings for both: origin access control for S3 and Lambda function URL origins, signed URLs and cookies with trusted key groups, viewer and origin TLS, dangling record and delegation takeover prevention, DNSSEC signing, registrar locks, logging and detection. It is for cloud security engineers, platform teams and DNS owners. Vendor-neutral CDN principles are in the CDN Security Guide and general takeover mechanics in the Subdomain Takeover and Dangling DNS Guide; this page stays on how to apply them in AWS.
This is an independent guide from NHI Mgmt Group, based on AWS's public documentation as of November 2026. It is not sponsored or reviewed by AWS. Product features change, so confirm settings against AWS's current documentation.
Key takeaways
- Use origin access control for every S3 and Lambda function URL origin. OAC with signing behaviour always, plus a bucket policy pinned to the distribution ARN with AWS:SourceArn, closes the direct-to-origin path; migrate any remaining origin access identity.
- Sign private content with trusted key groups. Key groups are managed through the API with IAM, need no root user, and support rotation without breaking unexpired URLs; Security Hub control CloudFront.17 checks for them.
- Retire DNS before you retire resources. Delete records and delegations first, then the bucket, distribution, IP or hosted zone, so no name ever points at something another party can claim.
- Treat the zone and the domain as privileged assets. Restrict route53:ChangeResourceRecordSets, keep the registrar transfer lock on, and sign public zones with DNSSEC where the parent supports DS records.
- Log both layers and alarm on the dangerous changes. CloudFront access logs, Route 53 public query logs in us-east-1 and CloudTrail record changes give you the evidence; Security Hub CloudFront controls give you the baseline.
The edge and DNS attack surface in AWS
A CloudFront distribution maps alternate domain names to cache behaviours and origins. Route 53 public hosted zones answer for those names, usually with alias records that point at the distribution. Each link in that chain can be abused in a different way.
| Weak point | What goes wrong | Primary control |
|---|---|---|
| Public or broadly shared S3 origin | Viewers bypass CloudFront, its WAF rules and its signed URL checks | Origin access control, S3 Block Public Access, bucket policy with AWS:SourceArn |
| Origin points at a deleted bucket | Another party creates the bucket name and serves content through your distribution | Remove the origin before deleting the bucket; Security Hub CloudFront.12 |
| Signed content keys | Root-managed key pairs, leaked private keys, long-lived URLs used as shared links | Trusted key groups, keys in a secrets store, short expiries, rotation |
| Viewer and origin TLS | Plain HTTP to viewers or origins, legacy protocols | Viewer protocol policy, recommended security policy, HTTPS-only origin protocol |
| Dangling DNS records | A name keeps pointing at a released IP, deleted bucket or removed service endpoint | Delete DNS first, inventory and monitor targets |
| Dangling delegations | Parent NS records point at Route 53 name servers you no longer control | Remove or match delegation records, DNSSEC |
| Zone and registrar control | Record changes or a domain transfer by an unauthorised principal | IAM scoping, transfer lock, CloudTrail alerts |
In MITRE ATT&CK terms, taking over a name you abandoned is resource development through T1584.001 Compromise Infrastructure: Domains, and changing records to redirect traffic supports T1557 Adversary-in-the-Middle.
Origin access control for S3 and Lambda origins
AWS recommends origin access control over the legacy origin access identity. OAC supports S3 buckets in all Regions, including opt-in Regions launched after December 2022, server-side encryption with AWS KMS (SSE-KMS), and dynamic PUT and DELETE requests to S3; OAI does not support these or needs workarounds. Security Hub control CloudFront.13 checks that S3 origins use OAC, and CloudFront.16 applies the same check to Lambda function URL origins, so the function can be invoked only on behalf of the named distribution.
Signing behaviour
| Console setting | API value | Behaviour | Use it when |
|---|---|---|---|
| Sign requests (recommended) | always | CloudFront always signs requests to the origin; the only option that guarantees HTTPS between CloudFront and S3 | Default for private origins |
| Do not override authorization header | no-override | Passes the viewer's Authorization header if present, signs only when it is absent; the header must be in the cache policy | Viewers sign their own requests to the origin |
| Do not sign requests | never | No signing; the bucket must be public or requests fail | Avoid for anything not intended to be public |
Bucket and key policies
- Bucket policy: allow principal cloudfront.amazonaws.com to call s3:GetObject on the bucket's objects, with a StringEquals condition on AWS:SourceArn set to the distribution ARN (arn:aws:cloudfront::account-id:distribution/distribution-id). Add s3:PutObject only for distributions that genuinely upload. Without the SourceArn condition, any distribution in any account could read the bucket through CloudFront.
- SSE-KMS: add a key policy statement that allows cloudfront.amazonaws.com kms:Decrypt (and kms:Encrypt and kms:GenerateDataKey* if the distribution writes), with the same AWS:SourceArn condition. See the AWS KMS Security Guide.
- Block Public Access: with OAC the bucket can stay fully private, so keep S3 Block Public Access on at account and bucket level. See the Amazon S3 Security Guide.
Migrating from OAI without an outage
- Add an OAC statement (cloudfront.amazonaws.com with AWS:SourceArn) to the bucket policy alongside the existing OAI statement, so CloudFront never loses access.
- Create the OAC and attach it to the S3 origin; with the CLI, remove OriginAccessIdentity from the origin configuration.
- Wait for deployment, test reads and writes, then remove the OAI statement. Until then, rollback is re-attaching the OAI.
For custom origins such as load balancers, OAC does not apply: restrict the origin to CloudFront at the network layer and require a secret header or mutual TLS, as described in the CDN Security Guide, and use HTTPS-only origin protocol (Security Hub CloudFront.9 and CloudFront.10).
Signed URLs, signed cookies and trusted key groups
Signed URLs and cookies restrict who can fetch private content through CloudFront. They are bearer credentials: anyone holding a valid one can use it until it expires.
Choosing the mechanism
- Signed URLs: for individual files such as an installer, or for clients that do not support cookies.
- Signed cookies: for many files at once, such as all segments of a video stream or a subscriber area, without changing URLs.
- Precedence: if both are present, CloudFront decides on the signed URL alone. If your normal URLs already use the query parameters Expires, Policy, Signature, Key-Pair-Id or Hash-Algorithm, CloudFront treats them as signed URLs and neither method works.
| Capability | Canned policy | Custom policy |
|---|---|---|
| End date and time | Yes | Yes |
| Start date and time | No | Yes, optional |
| Restrict by client IP address or range | No | Yes, optional |
| One policy for many files (wildcards in Resource) | No | Yes |
| URL length | Shorter | Longer, includes a base64-encoded policy |
CloudFront checks expiry when the request arrives. A download that starts before expiry can finish, but a restarted download or any range GET after expiry fails, which matters for large files. Prefer expiries of minutes, generated per request after your application has authenticated the user. IP restriction in a custom policy is useful for fixed partner networks but breaks for mobile users and users behind shared NAT.
Trusted key groups instead of CloudFront key pairs
AWS recommends trusted key groups over CloudFront key pairs because key pairs can only be managed by the root user in the console, cannot be automated and cannot be governed with IAM. Key groups are managed through the CloudFront API, so IAM policies can, for example, allow uploading public keys while denying deletion or requiring MFA for it. Limits documented by AWS: up to four key groups per distribution by default and up to five public keys per key group, against two active key pairs per account for the legacy method. Keys are RSA 2048 or ECDSA 256 in base64-encoded PEM.
- Protect the private key: it is a signing credential held by your application, so store it in a secrets manager, never in client code or source control. See the AWS Secrets Manager guide.
- Rotate without breaking users: add the new public key to a key group, keep the old key, switch the application to the new private key and test, then remove the old public key once every URL or cookie signed with it has expired.
- Cookie attributes: when your application issues signed cookies, set Secure and HttpOnly and scope Domain and Path to the protected area.
Viewer, origin and certificate settings
| Setting | Baseline | Security Hub control |
|---|---|---|
| Viewer protocol policy | redirect-to-https or https-only on the default and every cache behaviour; never allow-all | CloudFront.3 |
| Viewer TLS security policy | The recommended policy for custom certificates (TLSv1.2_2025 or TLSv1.3_2025 as checked by the control) | CloudFront.15 |
| Certificate | Custom certificate from AWS Certificate Manager, served with SNI rather than a dedicated IP | CloudFront.7, CloudFront.8 |
| Origin protocol | HTTPS only to custom origins; no deprecated SSL protocols | CloudFront.9, CloudFront.10 |
| Web application firewall | AWS WAF web ACL associated with every internet-facing distribution | CloudFront.6 |
| Default root object | Configured, so a request for the root does not expose a listing or error from the origin | CloudFront.1 |
| Logging | Access logging enabled | CloudFront.5 |
Alternate domain names need a certificate from ACM or another CA trusted by Mozilla whose subject alternative names cover the name. A name already attached to another distribution cannot be added again, and a wildcard such as *.example.com covers one level only. Because CloudFront routes on the Host header, a more specific name on another distribution wins over a wildcard on yours; review wildcard alternate domain names when teams share a parent domain. Requests whose Host header does not match the SNI and certificate are rejected with HTTP 421, which is CloudFront's domain fronting protection. See the AWS Certificate Manager and Private CA Guide and the AWS WAF and Shield Guide.
Preventing DNS takeover in Route 53
Dangling records
A dangling record is a name that still resolves to a target you no longer own. The common AWS cases are an A record for a released Elastic IP address, a CNAME or alias to an S3 website bucket that has been deleted, a CNAME to a removed service endpoint, and a distribution whose S3 origin bucket has been deleted. In each case someone else can acquire the IP, bucket name or endpoint and serve content under your name, which is the exact risk AWS describes for CloudFront.12: a third party creates the referenced bucket and serves its own content through your distribution.
- Order of retirement: delete or repoint the DNS record first, then delete the distribution, bucket, endpoint or IP. Build this order into decommissioning runbooks and infrastructure as code.
- Prefer alias records to AWS targets: alias records resolve to the current addresses of a named AWS resource rather than a copied IP, so there is no stale address to drift.
- Keep the bucket name: where an S3 bucket backed a public name, empty it but keep it, or keep the record removed, so the name cannot be re-registered against your record.
- Inventory and test: export every record set (ListResourceRecordSets) and resolve each target, flagging NXDOMAIN, unowned IPs and S3 NoSuchBucket responses. See the Subdomain Takeover Response Playbook.
Dangling delegations
AWS documents a separate risk: NS records in a parent zone that delegate a subdomain to four Route 53 name servers you no longer control, for example after the child hosted zone was deleted. Route 53 blocks those name servers from being assigned to a new hosted zone with the same name while the delegation records remain, but AWS states that this protection does not cover every scenario. AWS recommends that parent NS records always match the child zone's delegation set (check it with aws route53 get-hosted-zone), that you remove the NS records when you delete a child zone and re-add them only after it is recreated, that you delegate only through the immediate parent zone and only to name servers of a public hosted zone you control, that you create a hosted zone promptly on a reusable delegation set you have delegated to, and that you enable DNSSEC signing as an extra layer.
DNSSEC, registrar and change control
DNSSEC signing
Route 53 supports DNSSEC signing for public hosted zones only. Each key-signing key (KSK) is based on an asymmetric customer managed key in AWS KMS that you own and rotate; Route 53 manages the zone-signing key. Signing caps record TTLs at one week, and the chain of trust needs a DS record in the parent zone: if the parent's provider cannot publish DS records, the zone becomes unresolvable once signing is enabled. Multi-vendor and white-label name server configurations are not supported with signing. AWS strongly recommends CloudWatch alarms on DNSSECInternalFailure and DNSSECKeySigningKeysNeedingAction. For queries leaving your VPCs, Route 53 Resolver DNSSEC validation is a separate setting. See the DNSSEC Deployment Guide.
Registrar and zone permissions
- Transfer lock: keep it on for every Route 53 registered domain where the TLD supports it; WHOIS then shows clientTransferProhibited. Turn it off only for a planned transfer and treat the transfer authorisation code as a credential.
- Record change rights: route53:ChangeResourceRecordSets on a production zone is a privileged permission. Grant it to the deployment pipeline role, and use the route53:ChangeResourceRecordSetsNormalizedRecordNames and route53:ChangeResourceRecordSetsRecordTypes condition keys to limit teams to their own names and record types. See the AWS IAM Policies and Roles Guide.
- Hosted zone and domain actions: restrict DeleteHostedZone, DNSSEC key operations, ChangeResourceRecordSets on NS records and route53domains actions such as DisableDomainTransferLock to a small security or network role, ideally behind an SCP. See the AWS Organizations and SCPs Guide.
- Distribution changes: treat UpdateDistribution, origin changes and key group changes as production changes, made by pipeline roles from infrastructure as code. See the Domain and DNS Management Policy Template.
Logging, detection and metrics
| Source | What it gives you | Notes |
|---|---|---|
| CloudFront access logs | Every viewer request, status code, edge location and client IP | Security Hub CloudFront.5 checks standard logging only |
| Route 53 public DNS query logs | Query name, type, response code (NOERROR, NXDOMAIN), edge location, resolver IP, EDNS client subnet | CloudWatch Logs group must be in us-east-1; resolver caching means logs are a sample, not a complete record; set a retention period |
| Route 53 Resolver query logs | Queries made from your VPCs | Separate feature from public query logging |
| CloudTrail management events | ChangeResourceRecordSets, DeleteHostedZone, UpdateDistribution, origin access control and key group changes, domain lock changes | Route 53 and CloudFront are global; their events are recorded in us-east-1 |
| Security Hub CloudFront controls | CloudFront.1 to CloudFront.17 posture findings | CloudFront.12 runs periodically, not on change |
| CloudWatch DNSSEC metrics | DNSSECInternalFailure, DNSSECKeySigningKeysNeedingAction | Alarm on any non-zero value |
Alerts worth building: NS record changes in any public zone; any change to a production zone by a principal other than the pipeline role; DisableDomainTransferLock; a distribution switched from OAC to no signing or with an origin bucket removed; key group changes outside a rotation window; rising 403 rates on signed paths, which indicate expired or forged signatures being tried. See the DNS Logging and Detection Guide.
Metrics:
- Percentage of S3 and Lambda function URL origins using OAC with signing behaviour always (target 100).
- Distributions still using origin access identity or CloudFront key pairs (target 0).
- Dangling records found per monthly scan, and mean time from detection to removal.
- Percentage of public zones with DNSSEC signing where the parent supports DS records.
- Registered domains with transfer lock on, where the TLD supports it (target 100).
- Production record changes made outside the pipeline role per month (target 0).
Rollout plan
- Inventory: list distributions, origins, alternate domain names, key groups and key pairs, hosted zones, delegations and registered domains across all accounts.
- Turn on visibility: enable Security Hub CloudFront controls, CloudFront access logs and Route 53 query logging; route CloudTrail us-east-1 events to the SIEM.
- Fix takeover risk first: remove dangling records and delegations and resolve CloudFront.12 findings. These are the fastest to exploit.
- Close origin bypass: migrate OAI to OAC with the dual-statement method, pin bucket policies to distribution ARNs and enable Block Public Access. Pilot one low-traffic distribution first.
- Move signing to key groups: create key groups, move private keys into a secrets store, cut over, then delete root-managed key pairs.
- Tighten TLS and WAF: enforce HTTPS viewer policies, the recommended security policy and WAF association; test legacy clients in a staging distribution.
- Lock DNS: turn on transfer locks, scope record change permissions, then enable DNSSEC zone by zone with alarms in place. To roll back DNSSEC safely, remove the DS record at the parent and wait for its TTL before disabling signing.
Small versus large estates: a single team with a few distributions can do steps 3 to 5 in a week and rely on Security Hub for drift. Large organisations with many teams sharing a parent domain need delegated subzones per team, condition-key scoped record permissions, an organisation-wide SCP on domain and NS actions and a scheduled dangling-record scan.
Common failure patterns
- OAC without SourceArn: the bucket policy grants cloudfront.amazonaws.com without the distribution condition, so any distribution can read it.
- Signing keys in the codebase: the CloudFront private key ships in application configuration or a repository and is never rotated.
- Long-lived signed URLs used as share links: URLs valid for months are forwarded beyond the intended recipient.
- Child zone deleted, delegation left: NS records in the parent still point at name servers that no longer serve your zone.
- DNSSEC without alarms: a KSK problem goes unnoticed until resolvers that validate stop resolving the domain.
Framework mapping
| Control area | NIST SP 800-53 Rev 5 | NIST CSF 2.0 | ISO/IEC 27001:2022 Annex A | CIS Controls v8.1 |
|---|---|---|---|---|
| Origin access and least privilege | AC-3, AC-6 | PR.AA-05 | A.5.15, A.8.3 | 3 Data Protection, 6 Access Control Management |
| TLS for viewers and origins | SC-8, SC-13 | PR.DS-02 | A.8.24 | 3 |
| DNS integrity and DNSSEC | SC-20, SC-21, SC-22 | PR.PS-01 | A.8.20, A.8.21 | 9 Email and Web Browser Protections, 12 Network Infrastructure Management |
| Record and resource inventory | CM-8 | ID.AM-08 | A.5.9 | 1 Inventory of Enterprise Assets |
| Logging and monitoring | AU-2, AU-12, SI-4 | PR.PS-04, DE.CM-09 | A.8.15, A.8.16 | 8 Audit Log Management |
Practitioner checklist
- Attach OAC with signing behaviour always to every S3 and Lambda function URL origin and pin bucket and key policies with AWS:SourceArn.
- Migrate every remaining origin access identity using the dual-statement method.
- Replace CloudFront key pairs with trusted key groups, store private keys in a secrets manager and document rotation.
- Keep signed URL expiries to minutes for on-demand content and set Secure and HttpOnly on signed cookies.
- Enforce HTTPS viewer policies, the recommended TLS security policy, SNI certificates and a WAF web ACL.
- Delete DNS records and delegations before deleting buckets, distributions, IPs or hosted zones, and scan monthly for dangling records.
- Turn on registrar transfer locks and restrict record changes to pipeline roles with Route 53 condition keys.
- Sign public zones with DNSSEC where the parent supports DS records, with CloudWatch alarms on both DNSSEC metrics.
- Enable CloudFront access logs, Route 53 query logs in us-east-1 and alerts on NS, lock and origin changes.
Standards and references
- AWS: Restrict access to an Amazon S3 origin
- AWS: Specify signers that can create signed URLs and signed cookies
- AWS: Use signed URLs
- AWS: Security Hub controls for CloudFront
- AWS: Protection from dangling delegation records in Route 53
- AWS: Configuring DNSSEC signing in Amazon Route 53
- AWS: Public DNS query logging
- AWS: Locking a domain to prevent unauthorized transfer
Related NHI Mgmt Group resources: CDN Security Guide · Subdomain Takeover and Dangling DNS Guide · DNS Security Guide · AWS Security Guide