fix: prevent browsers from caching link redirects#302
Conversation
Link redirects are sent via sendRedirect() with no Cache-Control header. With the default redirectStatusCode of 301, browsers cache the redirect persistently, so a link that is later edited or deleted in the dashboard keeps resolving to the old target on the client (the request never reaches the worker again). This is surprising for a shortener whose links are mutable by design. Set 'Cache-Control: no-store' on both redirect paths (device redirect and the default redirect) so every visit re-hits the worker and reflects the current link state. Mirrors the no-store already used for the password / unsafe-warning / cloaking HTML responses.
|
Thanks for raising this. I understand the concern: for editable/deletable short links, browser-side caching of That said, the redirect status code is already configurable via I am not fully sure we should force For now, I would prefer not to change the current redirect caching behavior in this PR. Let us keep it open and see what others think. |
|
In principle, this kind of short link sharing shouldn't be considered a security measure by SEO. Of course, this is just my personal opinion. |
Problem
Link redirects are issued with
sendRedirect(event, finalTargetUrl, +redirectStatusCode)and noCache-Controlheader. SinceredirectStatusCodedefaults to301, browsers cache the redirect persistently.The practical consequence: after you edit or delete a link in the dashboard, the server correctly returns the new target / a 404 (verified with
curl), but any browser that already visited the old short link keeps redirecting to the stale target from its local 301 cache — the request never reaches the worker again. For a shortener whose links are mutable by design, this looks like "deleted links still work."Fix
Set
Cache-Control: no-storeon both redirect paths (the device-specific redirect and the default redirect), so every visit re-hits the worker and reflects the current link state.This mirrors the
no-storealready applied to the password / unsafe-warning / cloaking HTML responses in the same middleware. It is a minimal, behavior-preserving change — the redirect status code is left untouched (still configurable viaNUXT_REDIRECT_STATUS_CODE);no-storesimply stops clients from caching the hop.Testing
curl -I /<slug>→301with noCache-Control; deleting the link still resolves in a browser that visited it earlier.curl -I /<slug>→301+cache-control: no-store; edits/deletes take effect immediately on next visit.