A content delivery network only protects a site if the origin behind it cannot be reached directly and the cache never serves one user's data to another. Most organisations put a CDN in front of their web estate for performance and DDoS absorption, then assume the WAF, bot controls and TLS settings at the edge cover everything. In practice, origins stay reachable on public IP addresses, caches store authenticated pages, edge-to-origin traffic runs unencrypted or unvalidated, and the CDN account itself holds private keys and API tokens that few people govern. This guide covers origin protection on the major CDN platforms, cache safety, TLS between edge and origin, third-party scripts served from public CDNs, configuration governance and monitoring. It is for web platform engineers, cloud security architects and application security teams. Provider features are named to document how they work, not as recommendations.
Key takeaways
- Lock the origin, do not just hide it. Allow listing CDN IP ranges is not enough on shared platforms, because other customers send traffic from the same addresses. Combine network restriction with a per-customer proof such as mutual TLS, a secret header, a front door identifier or a private connection.
- Caching rules are security rules. A cache key that ignores a header the origin uses, or a rule that caches by file extension, can serve private pages to strangers or poisoned content to everyone. Use Cache-Control private and no-store on personalised responses and validate content type at the edge.
- Encrypt and validate edge to origin. Modes that use HTTPS for visitors but plain HTTP, or unvalidated certificates, to the origin leave the second hop open to interception.
- The CDN account is a privileged system. It holds TLS private keys, DNS, WAF rules and API tokens. A compromise there can redirect or rewrite an entire web estate.
- Third-party CDN scripts are supply chain dependencies. The polyfill.io incident showed that a script loaded from a public CDN domain can turn malicious overnight; pin with Subresource Integrity or self-host.
How a CDN changes the attack surface
A CDN terminates visitor TLS at edge servers, applies security rules, serves cached objects and forwards cache misses to the origin. That design creates four distinct trust boundaries, each with its own failure mode.
| Boundary | What can go wrong | Primary control | ATT&CK v20 |
|---|---|---|---|
| Internet to origin (bypassing the CDN) | Attackers find the origin IP and send attacks or floods directly, avoiding WAF and DDoS controls | Origin lockdown: private connectivity, mTLS, secret header, IP restriction | T1190, T1498, T1499 |
| Edge cache | Personalised responses cached and served to others; poisoned responses served to all visitors | Cache-Control discipline, cache key design, cache deception protections | T1659 Content Injection |
| Edge to origin connection | Interception or tampering between CDN and origin; spoofed CDN requests | HTTPS with certificate validation, authenticated origin pulls | T1557 |
| CDN control plane | Stolen API tokens or admin accounts change DNS, disable WAF or upload certificates | Scoped tokens, MFA, change control, audit logs | T1078, T1528 |
| Third-party CDN content | Shared libraries on public CDNs altered or the domain sold | Subresource Integrity, self-hosting, Content Security Policy | T1195.002, T1189 |
DDoS architecture is covered in the DDoS Protection Guide and WAF rule design in the Web Application Firewall Guide. This page focuses on what the CDN layer itself must get right.
Origin protection: closing the bypass
If an attacker can reach the origin directly, every edge control is optional. Cloudflare's origin protection guidance notes that historical DNS records keep pre-CDN IP addresses and recommends rotating origin IPs after onboarding, auditing DNS-only records such as SPF and TXT for origin addresses, and not hosting mail on the same server, because bounce messages reveal the server's IP. Certificate Transparency logs can also reveal origin hostnames such as origin.example.com; see the Certificate Transparency Guide.
Hiding the origin is a delay, not a control. The origin must reject traffic that did not come through your CDN configuration.
| Platform | Network restriction | Per-customer proof | Private connectivity |
|---|---|---|---|
| Amazon CloudFront to S3 | Bucket not public | Origin Access Control (OAC) signing with SigV4, bucket policy for cloudfront.amazonaws.com with an AWS:SourceArn condition naming the distribution | Not needed for S3 |
| Amazon CloudFront to ALB or custom origin | Security group limited to the AWS-managed prefix list for CloudFront | Secret custom origin header; ALB default rule returns 403 | VPC origins for internal ALBs |
| Azure Front Door | AzureFrontDoor.Backend service tag in NSG rules | Reject requests whose X-Azure-FDID header does not match your profile's Front Door ID | Private Link (Premium tier) |
| Cloudflare | Allow only Cloudflare IP ranges | Authenticated Origin Pulls with a zone-level or per-hostname certificate | Cloudflare Tunnel (outbound-only, no public IP) |
Why IP allow lists alone fail
Microsoft's Front Door documentation states the problem directly: other Azure customers use the same Front Door IP addresses, so an IP allow list cannot confirm the request came from your profile. An attacker can create their own Front Door, CloudFront distribution or Cloudflare zone pointing at your origin and pass straight through an IP-only rule, using a configuration with no WAF. The same logic applies to Cloudflare's global Authenticated Origin Pulls certificate, which Cloudflare says proves only that a request came from the Cloudflare network; a zone-level or per-hostname certificate unique to your account is the stricter option.
Choosing a method
- Private connectivity first: where the platform supports it (Private Link, VPC origins, tunnels), the origin needs no public listener at all. This is the strongest option and removes the IP discovery problem.
- mTLS second: authenticated origin pulls with your own client certificate give cryptographic proof per customer. Cloudflare notes that this does not scale well across many origin servers and does not apply to tunnel-connected hostnames.
- Secret header plus network restriction third: AWS's ALB guidance tells you to treat the header name and value as credentials and gives a four-step rotation: add a second header, accept both at the origin, remove the original, then stop accepting it. Store the value in a secrets manager, not in infrastructure code. See the Secrets Management Guide.
- S3 origins: AWS recommends OAC over the legacy Origin Access Identity, which lacks SSE-KMS support and newer Regions. Signing behaviour "never" requires a public bucket, so use "always". S3 static website endpoints cannot use OAC.
TLS between edge and origin
Visitor-facing TLS is usually well configured because it is visible. The edge to origin hop is not. Common CDN modes allow HTTPS for visitors with plain HTTP to the origin (Cloudflare's "Flexible") or HTTPS to the origin without certificate validation (Cloudflare's "Full"). Both leave the second hop open to interception or spoofing by anyone on the path; only full validation (Cloudflare's "Full (strict)", CloudFront origin protocol policy https-only with a certificate matching the origin hostname) closes it. Authenticated Origin Pulls requires Full or Full (strict) to work at all.
- Origin certificates: use a publicly trusted certificate or the provider's origin CA certificate, with automated renewal. Expired origin certificates are a common cause of outages; see the Certificate Expiry Outages and 47-Day TLS Certificates Guide.
- Minimum versions: set TLS 1.2 as the floor for origin connections (CloudFront's example uses OriginSSLProtocols TLSv1.2) and visitor connections, with TLS 1.3 preferred.
- Edge private keys: uploaded custom certificates mean the CDN holds your private keys. The Imperva breach exposed customer-provided SSL certificates and API keys for a subset of its Cloud WAF customers, and about 13,500 certificates had to be rotated. Use separate certificates for the edge and the origin, keep key rotation scripted, and prefer provider-managed edge certificates where your policy allows.
- HSTS at the edge: send Strict-Transport-Security from the edge once every hostname serves HTTPS, so downgrade attempts on visitor connections fail.
Cache risks: what must never be cached
RFC 9111 (HTTP Caching, Internet Standard since June 2022) sets the rules a shared cache like a CDN must follow. The safe defaults depend on the origin telling the cache what it may store, and CDN rules that override origin headers remove that safety net.
| Directive or mechanism | Meaning for a CDN (RFC 9111) | Use it for |
|---|---|---|
| Cache-Control: private | A shared cache must not store the response; a browser may | Personalised pages, account dashboards, API responses tied to a user |
| Cache-Control: no-store | No cache may keep any part of the request or response | Responses containing personal data, tokens or one-time content |
| Cache-Control: no-cache | May be stored but must be revalidated with the origin before reuse | Content that changes often but is not user-specific |
| s-maxage | Freshness lifetime for shared caches only, overriding max-age | Public content where the CDN should keep it longer than browsers |
| Authorization request header | A shared cache must not reuse the response for later requests unless public, s-maxage or must-revalidate permits it | Never mark authenticated API responses public |
| Vary | Adds named request headers to the cache key | Responses that differ by language, encoding or device; avoid varying on high-cardinality headers |
Web cache deception
Cache deception tricks the CDN into storing a dynamic, user-specific page because its URL looks static, for example /account/settings/x.css when the origin ignores the trailing path. The attacker then requests the same URL and reads the victim's page from cache. Defences are layered: have the origin send private or no-store on every authenticated response; avoid edge rules that cache by file extension regardless of origin headers; return 404 for unexpected path suffixes; and use content-type validation at the edge. Cloudflare's Cache Deception Armor, for example, only caches a response when the URL's extension matches the response's Content-Type, but Cloudflare notes that an origin Cache-Control header or an Edge Cache TTL rule can override it.
Web cache poisoning
Cache poisoning works the other way: the attacker gets a harmful response stored under a key that other visitors will request. It happens when the origin changes its response based on a request header (such as X-Forwarded-Host) that is not part of the cache key. Defences: strip or normalise unkeyed headers at the edge, include in the cache key every header the origin uses, and do not cache error responses for long. Both attack classes are covered in depth in the Web Cache Poisoning and Cache Deception Guide.
Private content through a CDN
- Signed URLs and cookies: for paid downloads or private media, use the CDN's signed URL or signed cookie features with short expiry, rather than obscure but static URLs.
- Purge capability: make sure the team can purge a specific URL or tag within minutes; when personal data has been cached by mistake, purging is part of incident response.
Third-party scripts from public CDNs
Many sites load JavaScript libraries from public CDN domains they do not control. According to Cloudflare, the polyfill.io domain was sold in February 2024 to a new owner, and on 25 June 2024 the service was reported to be injecting code that redirected some visitors to other sites; Cloudflare estimated the library was used on nearly 4% of all websites. Every one of those sites had delegated script execution to a domain whose ownership changed. This is ATT&CK T1195.002 Compromise Software Supply Chain delivered as T1189 Drive-by Compromise.
- Subresource Integrity: the W3C Subresource Integrity specification lets you add an integrity attribute with a SHA-256, SHA-384 or SHA-512 hash to script and link elements, so the browser refuses a file that has changed. Cross-origin SRI requires CORS (crossorigin attribute).
- Limits of SRI: SRI only works for static, versioned files. Services that generate content per browser (as polyfill.io did) cannot be pinned, which is a reason to self-host instead.
- Content Security Policy: a script-src allow list limits which domains can load code, and reporting shows new script sources appearing.
- Inventory: keep a list of every external script domain per site, with an owner, and review domain ownership changes. See the Top 10 Supply Chain Attacks.
CDN configuration and account governance
The CDN account controls DNS, certificates, WAF rules, redirects and edge code for every hostname behind it. Treat it as a privileged system.
- Admin access: SSO with phishing-resistant MFA for all console users, role-based access scoped per zone or distribution, and no shared logins. The Cloudflare Security Configuration Guide covers roles and API tokens for that platform in detail.
- API tokens as non-human identities: CI pipelines, Terraform and certificate automation all hold CDN tokens. Scope each token to the zones and permissions it needs, set expiry, restrict by source IP where supported, and rotate after staff changes. On AWS and Azure, use IAM roles and managed identities rather than long-lived keys.
- Configuration as code: manage distributions, cache rules and WAF settings through version control with peer review, so a change that disables the WAF or caches /account/* is visible before it ships.
- Edge code: edge functions (Lambda@Edge, CloudFront Functions, Workers) run on every request. Apply the same code review, dependency control and secret handling as the main application.
- Dangling records: when a distribution or CDN hostname is deleted, remove the DNS CNAME pointing to it first; otherwise an attacker may claim the hostname. See the DNS Security Guide, which covers subdomain takeover (ATT&CK T1584.001).
- Provider dependence: a CDN outage or misconfiguration takes the site with it. Document the fallback (secondary CDN, DNS failover to a protected origin) and test it, keeping in mind that failing over to an unprotected origin re-exposes it.
Implementation roadmap
- Inventory (weeks 1 to 2): list every hostname behind a CDN, its origin, how the origin is protected, TLS mode, cache rules and who holds API tokens. Include CDN accounts created outside central IT.
- Test origin exposure (weeks 2 to 3): from outside the CDN, try to reach each origin directly by IP and hostname, and search historical DNS and Certificate Transparency for old addresses. Any response other than a refusal is a finding.
- Fix edge to origin TLS (weeks 3 to 5): move every hostname to full certificate validation; deploy origin certificates first, then change the mode per hostname, watching error rates. Roll back per hostname if 5xx errors rise.
- Lock the origin (weeks 4 to 8): pilot one application with private connectivity or mTLS, then roll out. For secret headers, deploy the origin rule in log-only mode first to confirm only CDN traffic carries the header, then enforce. Rotate origin IPs after enforcement.
- Cache review (weeks 4 to 8): audit edge rules that override origin headers or cache by extension; add private or no-store to authenticated responses at the origin; enable content-type validation; test with authenticated and unauthenticated sessions.
- Third-party scripts (weeks 6 to 10): inventory external scripts, add SRI or self-host, and introduce CSP in report-only mode before enforcing.
- Governance and monitoring (ongoing): move configuration to code, scope and expire API tokens, and stream CDN logs and audit events to the SIEM.
A small organisation with one site on one CDN can do most of this in a fortnight: enable the provider's strict TLS mode, an origin lock method, and a review of cache rules. Large estates with multiple CDNs need a platform standard per provider and an exceptions register.
Detection and measurement
| Signal | Source | What it suggests |
|---|---|---|
| Requests at the origin without the CDN marker (header, client certificate or provider source range) | Origin web server or load balancer logs | Origin bypass or misconfigured lock |
| Cache hits on authenticated paths, or the same Set-Cookie served from cache to many clients | CDN request logs with cache status field | Cache deception or a cache rule caching private content |
| Spike in cache misses or unusual query string and header variety | CDN analytics | Cache-busting floods or poisoning probes |
| Changes to TLS mode, WAF state, DNS records, cache rules or certificates | CDN audit log | Unauthorised configuration change or token misuse |
| New script domains in CSP reports | CSP reporting endpoint | Injected or newly added third-party code |
Metrics that show it is working:
- Percentage of CDN-fronted origins that refuse direct connections (target 100%).
- Percentage of hostnames using validated TLS to the origin.
- Number of edge cache rules that override origin Cache-Control on dynamic paths (target zero, or documented exceptions).
- Percentage of external scripts protected by SRI or self-hosted.
- Percentage of CDN API tokens with scoped permissions and an expiry date.
Common failure patterns
- IP allow list as the only origin lock: anyone with an account on the same CDN can reach the origin through their own configuration without your WAF.
- Origin still on its old IP: the CDN was added but the origin address never changed, so historical DNS points straight at it.
- Flexible or unvalidated TLS to the origin: the padlock in the browser hides a plain HTTP or unauthenticated second hop.
- Cache everything rules: a performance rule that caches by extension or overrides origin headers exposes account pages through cache deception.
- Unpinned third-party scripts: libraries loaded from public CDN domains without SRI or CSP, as in the polyfill.io case.
- Ungoverned CDN credentials: long-lived API tokens in CI and edge certificates with keys nobody rotates; the Imperva case shows a provider holding customer keys becomes a target in its own right.
Framework mapping
| Control area | NIST SP 800-53 Rev. 5 | NIST CSF 2.0 | ISO/IEC 27001:2022 Annex A |
|---|---|---|---|
| Origin lockdown and boundary | SC-7 Boundary Protection | PR.IR-01 | A.8.20 Networks security, A.8.22 Segregation of networks |
| DDoS absorption at the edge | SC-5 Denial-of-service Protection | PR.IR-01 | A.8.20 Networks security |
| Edge and origin TLS, certificates | SC-8, SC-12 | PR.DS-02 | A.8.24 Use of cryptography |
| Cache rules and configuration as code | CM-6 Configuration Settings | PR.PS-01 | A.8.9 Configuration management |
| Third-party scripts and integrity | SI-7, SA-9 | GV.SC-07 | A.5.21 Managing information security in the ICT supply chain |
| CDN logs and audit events | AU-6, SI-4 | DE.CM-01 | A.8.15 Logging, A.8.16 Monitoring activities |
Practitioner checklist
- Inventory every CDN-fronted hostname with its origin, origin lock method, TLS mode and cache rules.
- Test each origin from outside the CDN and confirm it refuses direct connections.
- Use private connectivity or mTLS with your own certificate; where only headers are available, combine a rotated secret header with provider network restrictions.
- Rotate origin IP addresses after locking, and remove origin addresses from SPF, TXT and other public records.
- Enforce validated HTTPS to every origin with TLS 1.2 as the minimum.
- Send private or no-store on every authenticated response and remove edge rules that override it on dynamic paths.
- Normalise unkeyed headers at the edge and keep the cache key aligned with what the origin varies on.
- Add SRI to external scripts or self-host them, and introduce a Content Security Policy.
- Scope, expire and vault CDN API tokens; require SSO and MFA for console access; manage configuration as code.
- Delete DNS records before deleting CDN resources, and alert on CDN configuration changes.
Standards and references
- IETF: RFC 9111 HTTP Caching
- W3C: Subresource Integrity
- NIST: SP 800-53 Rev. 5
- AWS: Restrict access to an Amazon S3 origin
- AWS: Restrict access to Application Load Balancers
- Microsoft Learn: Secure traffic to Azure Front Door origins
- Cloudflare: Authenticated Origin Pulls
- Cloudflare: Automatically replacing polyfill.io links with Cloudflare's mirror
Related NHI Mgmt Group resources: Web Cache Poisoning and Cache Deception Guide · DDoS Protection Guide · Cloudflare Security Configuration Guide · Load Balancer Security Guide · DNS Security Guide