
If one signed-in visitor sees another person's name, account page, or order details after a site is put behind a CDN, treat it as a possible data exposure. Stop caching the affected routes, purge any copies already at the edge, and preserve enough logs to investigate. Logging out or clearing a browser cache will not remove a private page stored in a shared CDN cache.
Confirm which layer served the response
Use two test accounts in separate browser profiles or isolated sessions. Request the same affected URL and compare the smallest account-specific field needed to tell the responses apart. Record the request URL and time, response status, Cache-Control, Age, Vary, and the CDN's cache-result header or logs. Cloudflare's CF-Cache-Status and CloudFront cache-result logs are examples; names and meanings vary by provider. Never paste real users' tokens or order data into a ticket. If live data has crossed accounts, follow your incident-response process while preserving evidence.
For an anonymous baseline, inspect the headers without downloading the body:
curl -sS -D - -o /dev/null 'https://www.example.com/account/'
Use only disposable test credentials when checking authenticated requests, and do not put real cookies in a shared terminal history. Compare the result with a controlled request to the origin that bypasses the CDN. Keep the intended Host header and TLS SNI when connecting directly, or you may test a different virtual host. If the origin itself serves the same person's content to both sessions, inspect the application and origin cache. If the origin separates users but the edge does not, inspect CDN rules and cache keys. An edge HIT alone is not proof of a leak: verify the body and the two independent identities.
Why a private page can enter a shared cache
A cache key decides which requests share an object. Host, path, and query parameters commonly matter; whether cookies and authorization headers matter depends on the configured policy. A broad “cache everything” rule covering /account/ or /api/me, combined with a cache key that ignores identity, can make one user's response available to another. Adding every cookie to the key is not a sound substitute for excluding private pages: it increases key cardinality and leaves rule mistakes possible.
The HTTP directives have different meanings. Cache-Control: private prevents a shared cache from storing the response; no-store tells caches not to store it. no-cache does not mean “never cache”: a stored response must be validated before reuse. Vary: Cookie describes variants, but should not be the only safeguard for an account page. Check product-specific overrides as well. In particular, Amazon CloudFront documents that a cache policy with a minimum TTL greater than zero may cache a response even when its origin sends no-cache, no-store, or private. Do not assume an origin header wins over every edge rule.
Likewise, a Set-Cookie header is not a universal guarantee of safe bypass. Inspect custom CDN rules, edge code, reverse proxies, and page-cache plugins that may rewrite either the response or its cache behavior.
Contain the leak, purge, then retest
First, bypass shared caching for account and administration pages, cart and checkout routes, and APIs that return user-specific data. Map these examples to your actual routes. Check whether a wildcard rule takes precedence over the exception. If the home page renders a name or other account details into HTML, either stop sharing that HTML at the edge or change the rendering design.
Second, have the origin label private responses explicitly:
Cache-Control: private, no-store
Keep appropriate caching for public assets; disabling the entire site's cache is usually unnecessary. The origin header is an additional safeguard, not a replacement for checking CDN policy precedence.
Third, purge affected objects. Account for alternate hosts, query strings, device or geographic variants, and the provider's actual cache-key settings. Purging only one URL may leave other variants behind. Choose an appropriately scoped URL, prefix, or tag purge if your provider offers it; record the purge and rule-change times and keep relevant logs.
Finally, test repeatedly with two fresh isolated sessions and an anonymous session. Confirm that no account-specific fields cross between users, that the sensitive route reports bypass or an equivalent non-cache result, and that the origin or application cache is not serving a stale private object. Two tabs in one browser profile usually share cookies and are not a reliable two-user test.
Check NGINX if it caches behind the CDN
An NGINX proxy_cache at the origin can leak a response even after the CDN is fixed. For a route that truly must never be shared, the clearest configuration is often not to enable proxy_cache there, or to set proxy_cache off;. If your configuration instead needs conditional controls, the following is illustrative; replace session with the real cookie name and test it against the rest of your configuration:
location /account/ {
proxy_pass http://app_backend;
proxy_cache_bypass $http_authorization $cookie_session;
proxy_no_cache $http_authorization $cookie_session $upstream_http_set_cookie;
}proxy_cache_bypass prevents using an existing cache entry for a matching request. proxy_no_cache prevents storing a matching response. They solve different halves of the problem. Back up the current configuration, run nginx -t, reload only after the test passes, and be ready to restore the previous configuration and retest if behavior changes unexpectedly.
The lasting fix is to separate genuinely public content from identity-dependent HTML and APIs in both CDN and origin policies. Include independent-session checks, an anonymous request, the edge cache result, and an origin comparison in your release tests. A single successful test with one logged-in account cannot rule out a cross-user cache leak.
References
Documentation checked: September 22, 2026.