← notes

A cached page that handed every reader someone else's token

Oct 5, 2026

Signed-out pages were cached with one reader's CSRF token and served to everyone. The specs never saw the cache.

Saving a flight while signed out failed on the live site with a 422. The button was new. The cause was not, and it was also breaking the subscribe card and the Monday email signup.

A signed-out landing page or route board is served public, max-age=600. The proxy in front of Puma caches that page in memory and removes its Set-Cookie. So the page a reader gets carries the CSRF token minted for whoever asked first, and no session cookie to match it. Rails rejects the post, correctly.

Checked in production: Puma inside the container sent Set-Cookie, and the proxy, serving the same page on a cache miss, removed it. A cookieless POST with the page’s own token answered 422. The specs never saw it, because Rack::Test talks to Puma directly and there is no cache in between.

The fix skips the token on the three endpoints those cached pages post to, and nowhere else. A post is accepted only when the browser says it came from this site: Sec-Fetch-Site: same-origin, or an Origin equal to the request’s own base URL. A cross-site page cannot set either header. Anything else gets a 403, including a post with neither. Signed-in pages are never publicly cached, so every other form keeps its token.

The suite ran to 1,671 examples, and all of them had passed before too.