Agent Wranglers

Requests and files Required

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.

Example

app.use('/account', (req, res, next) => { res.set('Cache-Control', 'private, no-cache'); next(); });
@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.

For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers security testing playbook: https://agentwranglers.se/playbook/adversarial-testing/requests-and-files/private-responses-uncached.