Skip to content

fix(vtex,blocks): prevent caching authenticated proxy responses (cross-user data leak) - #413

Open
JonasJesus42 wants to merge 1 commit into
mainfrom
fix/vtex-proxy-cache-hardening
Open

fix(vtex,blocks): prevent caching authenticated proxy responses (cross-user data leak)#413
JonasJesus42 wants to merge 1 commit into
mainfrom
fix/vtex-proxy-cache-hardening

Conversation

@JonasJesus42

@JonasJesus42 JonasJesus42 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Closes/refs #412.

Problem

Authenticated VTEX responses routed through the proxy (/account, /api/sessions, /api/oms/user/orders) could be served with Cache-Control: public and cached at shared edge layers (Cloudflare/CloudFront), leaking one user's orders/data to another. Confirmed in production on a proxied storefront.

Fixes

  • apps-vtex utils/proxy.ts: proxyToVtex and createVtexCheckoutProxy now force Cache-Control: private, no-store, no-cache, must-revalidate + CDN-Cache-Control: no-store on authenticated proxy responses by default (opt-out via hardenAuthenticatedCache: false), exempting genuinely public static assets (/files, /arquivos, /assets/vtex, /XMLData).
  • apps-vtex utils/vtexId.ts: extractVtexAuthCookie now also matches the account-suffixed cookie VtexIdclientAutCookie_{account}, and parseVtexAuthToken treats a present opaque (non-JWT) token as logged-in. Previously isLoggedIn was false for real sessions, so any logged-in cache bypass never fired.
  • blocks sdk/cacheHeaders.ts: PRIVATE_PREFIX_RE now covers myaccount and pt-BR account routes (minha-conta, meus-pedidos, pedidos) so they don't fall through to the cacheable listing default.

Notes

Cache hardening is on by default — this changes behavior for existing proxy consumers, which is the intended safe default for authenticated endpoints. Static assets remain cacheable. Site-side workaround already deployed at deco-sites/bagaggio-tanstack#278.


Summary by cubic

Prevents caching of authenticated VTEX proxy responses to stop cross-user data leaks. Forces private/no-store headers by default, fixes auth detection, and expands private route patterns.

  • Bug Fixes

    • apps-vtex: In utils/proxy.ts, proxyToVtex and createVtexCheckoutProxy now set Cache-Control: private, no-store, no-cache, must-revalidate and CDN-Cache-Control: no-store for non-static responses; static asset prefixes /files, /arquivos, /assets/vtex, /XMLData are exempt.
    • apps-vtex: In utils/vtexId.ts, extractVtexAuthCookie matches the account-suffixed cookie; parseVtexAuthToken treats opaque (non-JWT) tokens as logged in to ensure cache bypass works.
    • blocks: In sdk/cacheHeaders.ts, PRIVATE_PREFIX_RE now covers myaccount, minha-conta, meus-pedidos, and pedidos to prevent account pages from being edge-cached.
  • Migration

    • Authenticated proxy responses are now non-cacheable by default. To opt out for a specific proxy, pass hardenAuthenticatedCache: false to proxyToVtex or createVtexCheckoutProxy.

Written for commit a98acd0. Summary will update on new commits.

Review in cubic

…s-user leak)

Authenticated VTEX proxy responses (/account, /api/sessions,
/api/oms/user/orders) could be served with `Cache-Control: public` and
cached at shared edge layers, leaking one user's orders/data to another.
Root cause was threefold (see #412):

- apps-vtex/utils/proxy.ts: neither proxyToVtex nor createVtexCheckoutProxy
  normalized Cache-Control, so the raw origin directive (or a public listing
  profile) passed through. Now force `private, no-store` +
  `CDN-Cache-Control: no-store` on authenticated proxy responses by default
  (opt-out via hardenAuthenticatedCache), exempting static assets.
- apps-vtex/utils/vtexId.ts: extractVtexAuthCookie ignored the
  account-suffixed cookie variant, and parseVtexAuthToken treated opaque
  (non-JWT) tokens as logged-out — so isLoggedIn was false for real sessions
  and any logged-in cache bypass never fired. Match the suffixed variant and
  treat a present opaque token as logged-in.
- blocks/sdk/cacheHeaders.ts: PRIVATE_PREFIX_RE missed `myaccount` and pt-BR
  account routes, letting them fall through to the cacheable `listing`
  default. Cover them.

Refs #412

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JonasJesus42
JonasJesus42 requested a review from a team July 29, 2026 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant