Safeguard
Application Security•

ASVS 5.0 V14.2.2: Keep Sensitive Data Out of Shared Caches

ASVS 5.0 V14.2.2 (Level 2): stop load balancers and app caches from storing sensitive responses, or purge them after use. Configs and tests.

Safeguard Security Team
2 min read

ASVS 5.0 V14.2.2 is a Level 2 requirement. Sensitive data must not be cached in server side components such as load balancers, reverse proxies and application caches. If it is cached anyway, it must be securely purged after use.

Why it matters

A shared cache serves whatever it stored to whoever asks for the same key. If a personalized response is stored under a key that does not include the user, the next visitor receives someone else's account page. Caches also keep data longer than expected, and they are often not covered by the same encryption and access rules as the database.

How to implement it

Tell shared caches not to store the response:

Cache-Control: private, no-store

private stops shared caches from storing it, and no-store stops anyone from keeping it. Set this on all authenticated and personalized responses, not only on a few.

Set it centrally so no route is forgotten:

app.use("/api", requireAuth, (req, res, next) => {
  res.set("Cache-Control", "private, no-store");
  next();
});

For application caches such as Redis, decide per key:

# Cache the lookup of a public product, never the personal profile
cache.set(f"product:{pid}", product_json, ex=300)
# If a sensitive value must be cached, use a short TTL and delete after use
cache.set(f"otp:{user_id}", code_hash, ex=120)
...
cache.delete(f"otp:{user_id}")

Include identity and tenant in the cache key whenever personalized data is cached at all. In the CDN or proxy, configure rules that bypass cache when an Authorization or session cookie is present.

How to test it

  1. Request an authenticated page twice as user A and check the response headers for Cache-Control: private, no-store and a cache status header that says miss or bypass.
  2. Request the same URL as user B, or anonymously, immediately afterward. You must not see A's data.
  3. Inspect the cache store for keys and values that contain personal data or tokens, then check expiry on each.

Common mistakes

  • Relying on the browser header while a CDN rule overrides it with its own caching default.
  • Cache keys that include the path but not the user or tenant.
  • Long TTLs on tokens and one time codes.
  • Caching error responses that echo private input.

Quick check

Is Cache-Control: no-cache enough?

No. no-cache permits storing but requires revalidation. Use no-store for sensitive responses.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.