Make WordPress Core

Opened 2 years ago

Closed 20 months ago

Last modified 15 months ago

#61942 closed defect (bug) (fixed)

Add "no-store" to Cache-Control header to prevent unexpected cache behavior

Reported by: kkmuffme Owned by: johnbillion
Priority: normal Milestone: 6.8
Component: Security Version:
Severity: normal Keywords: has-patch has-unit-tests
Cc: Focuses:

Description

https://core.trac.wordpress.org/ticket/21938

Added no-store, private to Cache-Control in WP 6.1 for logged in users.
However, since this ticket was more than a decade old and created in an age before widespread reverse-proxying (CDNs), this is a problem: since those can and will store responses that have no-cache (but not no-store): https://developers.cloudflare.com/cache/concepts/cache-control/
Either by default or depending on the configuration.

Practically, not all actions are for logged in users - e.g. you have a cart/checkout/thankyou page, which will end up in a proxy-cache bc of this bug and could end up being served from cache incorrectly.

The no-store, private should be added for non-logged in users too/the user logged in condition removed

Change History (9)

This ticket was mentioned in PR #7257 on WordPress/wordpress-develop by @devansh2002.


2 years ago
#1

  • Keywords has-patch added

Remove logged-in check for no-store, private Cache-Control
Trac ticket: https://core.trac.wordpress.org/ticket/61942

#2 @ayeshrajans
2 years ago

  • Keywords has-patch removed

I agree with what the ticket proposes, but we are already doing this for logged in users.

PR 7257 seems wrong, it removes the is-logged-in check for some reason, but it's not what we should be doing because the existing code seems correct to me.

#3 @johnbillion
22 months ago

  • Keywords has-patch needs-testing reporter-feedback added

@kkmuffme What do you think about the comment above from @ayeshrajans ?

#4 @kkmuffme
22 months ago

Sorry, but @ayeshrajans makes no sense to me

it removes the is-logged-in check for some reason

The reason is exactly the issue described by me in the OP

the existing code seems correct to me

Again: did you read the original bug I reported above? Why does it seem correct to you?

#5 @johnbillion
20 months ago

  • Milestone Awaiting Review6.8
  • Owner set to johnbillion
  • Status newreviewing

#6 @johnbillion
20 months ago

  • Keywords has-unit-tests added; needs-testing reporter-feedback removed

#7 @johnbillion
20 months ago

  • Resolutionfixed
  • Status reviewingclosed

In 59724:

Security: Always include the no-store and private directives in the Cache-Control header when setting headers that prevent caching.

The intention of these headers is to prevent any form of caching, whether that's in the browser or in an intermediate cache such as a proxy server. These directives instruct an intermediate cache to not store the response in their cache for any user – not just for logged-in users.

This does not affect the caching behaviour of assets within a page such as images, CSS, and JavaScript files.

Props kkmuffme, devansh2002, johnbillion.

Fixes #61942

#8 @westonruter
15 months ago

@devansh2002 @johnbillion Is no-store really necessary to have been added here? This directive breaks (generally) the browser's bfcache, greatly slowing down site back/forward navigations. The private directive should suffice, as noted in the linked Cloudflare docs above:

private — Indicates the response message is intended for a single user, such as a browser cache, and must not be stored by a shared cache like Cloudflare or a corporate proxy.

When a back/forward navigation is restored without bfcache, the state of the page will usually reset (aside from static non-JS form fields), potentially resulting in data loss. I've been working on a PR for WooCommerce that enabled bfcache for the Cart, Checkout, and Account pages and it can have a dramatic improvement to the user experience.

The remaining concern which originally introduced no-store and private in #21938 (via [55968]) was a privacy fix to prevent accessing authenticated pages from history after the user is logged out. I think there is a better way to handle this via a pageshow event handler client-side which I'm currently working on prototyping and writing up a proposal. This would entail the removal of no-store from being sent in the Cache-Control header.

#9 @westonruter
15 months ago

In order to enable bfcache, I've opened #63636 to propose removing no-store but keeping private.

Note: See TracTickets for help on using tickets.