Make WordPress Core

Opened 15 months ago

Closed 9 months ago

Last modified 4 months ago

#61942 closed defect (bug) (fixed)

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

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

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.


15 months 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
14 months 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
12 months ago

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

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

#4 @kkmuffme
11 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
10 months ago

  • Milestone changed from Awaiting Review to 6.8
  • Owner set to johnbillion
  • Status changed from new to reviewing

#6 @johnbillion
9 months ago

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

#7 @johnbillion
9 months ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

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
4 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
4 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.