RoastMyOpsec

News

ETag vs Cache-Control for Personalized Pages

August 28, 2023

ETag vs Cache-Control for personalized pages is a byte validator versus who may store the response. Cache-Control (private, no-store, no-cache) says whether a shared CDN may keep the HTML. An ETag is a validator for later If-None-Match revalidation. A user-specific page with Cache-Control: public and a stable ETag is how one person's dashboard can be served to the next. Cookies on the response without private/no-store is the same class. RoastMyOpsec inspects Cache-Control versus Set-Cookie on the landing HTML. It does not score ETag, does not send If-None-Match as a poisoning test, and does not brute-force validators.

The practical difference

Cache-Control is policy: public, private, max-age, no-store. ETag is a name for a body version. Strong ETags mean byte-identical. Weak ETags (W/) mean semantically close. Neither header authenticates the user. Authorization still belongs in the app.

Static marketing assets want public plus ETag or hashed filenames. Account HTML wants no-store or private plus Vary: Cookie (and usually no shared ETag that ignores the session).

How to choose validators

Public immutable assets: long max-age, filename hash, ETag optional. Personalized HTML: Cache-Control: private, no-store (or max-age=0, must-revalidate with private) and do not let the CDN cache by URL only. If you must revalidate, the ETag must not be identical across users for the same URL. See Cache-Control public vs private.

Page typeCache-ControlETag roleTakeaway
Hashed JS/CSSpublic, max-age long, immutableOptional; filename already uniqueShare freely
Marketing HTMLpublic with a short max-age, or CDN TTLFine if the body is the same for everyoneNo Set-Cookie on that response
Logged-in HTMLprivate, no-store (or equivalent)Must not be a shared user-agnostic tagThe miss if public + cookie
API JSON with cookiesprivate / no-storeSame ruleSee CORS + cookies separately

What the roast can prove

Set-Cookie plus a public cache directive on the landing response can surface. A present ETag is not a finding. Confirm CDN keys include cookie or authorization where the body varies. Pair with HttpOnly cookies if the personalized page also sets a session.

Common mistakes

The first mistake is CDN cache-everything on /dashboard.

The second mistake is a inode-based ETag that is identical for every user of the same template.

The third mistake is treating ETag as an access-control header.

Free audit the URL you own

RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.

Free audit now

FAQ

Is an ETag a vulnerability?
Not by itself. A shared cache key plus a user-specific body is. Fix Cache-Control and the CDN key.
Should I remove ETags everywhere?
No. Static assets benefit. Personalized HTML should not be publicly cacheable whether or not an ETag exists.
Does RoastMyOpsec score ETag?
No. It compares Cache-Control to Set-Cookie on the landing response. No cache-poisoning tests.

Sources

Related guides