APS-46Required
Keep private pages out of shared caches
Mark every reply that depends on the logged-in user Cache-Control: private, and never let a CDN cache by file extension alone.
How to do it
Set the header once in the middleware that loads the session, so no route can forget it. Use private, no-cache for ordinary account pages. Use no-store only for payment, health or identity pages, because it also blocks the back/forward cache. JSON answers from an API follow API cache headers. Configure the CDN to respect the origin's Cache-Control, and to skip caching when a request has a session cookie or an Authorization header. Return 404 for unknown paths under private routes, such as /account/x.css. This stops web cache deception, where a CDN stores a private page because its address ends in .css.
Examples
JavaScript example
app.use('/account', (req, res, next) => { res.set('Cache-Control', 'private, no-cache'); next(); });
Python example
@app.after_request
def private_cache(response):
if request.path.startswith("/account"):
response.headers["Cache-Control"] = "private, no-cache"
return response
How to check
Logged in as a test user, request /account/profile and /account/profile/x.css through the CDN. Then request both again with no cookie. Neither reply without a cookie contains the test user's data. The profile reply carries Cache-Control: private, and the x.css address answers 404.
Sources
Related rules
- WEB-42 Cache files for a year and pages briefly in Website
- WEB-53 Keep the back button instant in Website
- WEB-227 Serve the last good page when the server fails in Website
- API-14 Set caching headers on every response in API design
- SCL-43 Cache public pages at the edge for a few seconds in Scaling
- AGT-17 Send cache hints and a stable order with every list in Agents as users
- MED-19 Give every file version its own address in Files and media
- APS-47 Keep unkeyed headers from changing cached pages in Application security
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/application-security/requests-files-and-caches/private-responses-uncached">Agent Wranglers application security playbook</a>. In code you write, add a comment next to it with the same link.