Logout Does Not Necessarily Clear the Browser's Back-Forward Snapshot
A browser's back-forward cache, often called bfcache, can keep an entire page in memory so that Back and Forward navigation feel immediate. MDN explains that a page restored from bfcache may not be revalidated with the server. That creates a gap between server-side logout and what a user can still see in the browser interface. The session cookie may be gone while the previously rendered page is restored from local memory.
The risk grows with shared devices and sensitive dashboards. A user opens an invoice or account page, signs out, and hands the device to another person. The second person presses Back. If the page is restored from bfcache, the old DOM may appear before the application has checked the session again. Client-side code that only runs during initial load may not refresh the view. Even when the application redirects quickly, the restored snapshot can reveal information during the transition.
Cache-Control: no-store is one relevant control. MDN notes that a response with no-store is excluded from bfcache in supported browsers. The header also has broader effects on HTTP caching and performance, so teams should apply it to pages whose content is genuinely sensitive rather than every response. no-cache is not equivalent because it permits storage and requires revalidation before reuse. The browser's bfcache and the HTTP cache are related but distinct mechanisms.
Client-side lifecycle handling adds another layer. The pageshow event includes a persisted property that can identify a restored page. A logout flow can mark the local state as signed out, replace sensitive DOM content, and make a fresh authorization request before showing protected data. However, a JavaScript handler is not a substitute for the server rejecting the old session. The application should also abort or reconnect WebSocket and event streams after restoration.
Server-side logout should revoke the session, clear cookies with the correct attributes, and invalidate refresh tokens or device grants. If the application uses multiple tabs, decide whether logout is global. Broadcast a logout event to other tabs and handle the event idempotently. A tab that was offline during logout should verify its session before rendering data when it becomes active again.
The deployment needs a test that matches the threat. Sign in with account A, open a sensitive page, sign out, navigate Back, and inspect what is visible. Repeat with the network offline after logout and after a short delay. Check whether the page appears from bfcache, whether the session is rejected, and whether cached API responses remain accessible. Test both the browser's rendered view and the underlying requests.
Developers should also audit client storage. IndexedDB, localStorage, in-memory stores, and service worker caches can retain data even when a page is no longer in bfcache. A logout flow that clears one storage mechanism but leaves another can produce the same disclosure. Define a data retention policy for each storage surface and remove sensitive values that are no longer needed. Avoid placing authorization decisions in client storage that the server cannot verify.
The safest design assumes that logout is a distributed state change. The server revokes the session, the client clears its sensitive surfaces, and the browser is instructed not to keep a restorable snapshot of the protected page. Each layer has limits, and none should be treated as complete alone. The practical goal is to make the old page useless even if the browser shows it briefly.


