mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
Harden invite token-in-path against cache and index leaks
Extend the /c/ edge defence (no-store, noindex, no-referrer) to the /invite/<hlv_token> surface — the invite secret rides in the path, so no CDN may cache it and no crawler may index the URL.
This commit is contained in:
1 parent
c1eb618dcc
commit
03bde8d40c
2 files changed
+17
-1
No files matched your search
@@ -48,6 +48,17 @@ describe("proxy.ts /invite public-allowlist (v1.17.0)", () => {
|
||||
expect(res.headers.get("location")).toBeNull();
|
||||
});
|
||||
|
||||
it("hardens the token-in-path surface against cache / index / referrer leaks", () => {
|
||||
// Mirror the `/c/<token>` edge defence — the secret rides in the path,
|
||||
// so no CDN may cache it and no crawler may index the URL.
|
||||
const res = proxy(makeRequest(`/invite/${VALID_TOKEN}`));
|
||||
expect(res.headers.get("Cache-Control")).toBe(
|
||||
"no-store, no-cache, must-revalidate",
|
||||
);
|
||||
expect(res.headers.get("X-Robots-Tag")).toBe("noindex, nofollow");
|
||||
expect(res.headers.get("Referrer-Policy")).toBe("no-referrer");
|
||||
});
|
||||
|
||||
it("still redirects unauthenticated requests for protected pages", () => {
|
||||
// Negative check — confirms the fixture would catch a real
|
||||
// regression. `/insights` is not public.
|
||||
|
||||
+6
-1
@@ -279,7 +279,12 @@ export function proxy(request: NextRequest) {
|
||||
// the header, and the token must never reach a search index.
|
||||
// - `Referrer-Policy: no-referrer` so the token-bearing URL is not
|
||||
// leaked in the `Referer` of any outbound navigation from the page.
|
||||
if (pathname.startsWith("/c/")) {
|
||||
//
|
||||
// v1.17.0 — `/invite/<hlv_token>` (iOS #16) carries an equally sensitive
|
||||
// secret in the path, so it earns the same edge defence even though it is
|
||||
// a pure server redirect: no shared proxy / CDN may cache it and no
|
||||
// crawler may index the token-bearing URL.
|
||||
if (pathname.startsWith("/c/") || pathname.startsWith("/invite/")) {
|
||||
response.headers.set(
|
||||
"Cache-Control",
|
||||
"no-store, no-cache, must-revalidate",
|
||||
|
||||
Reference in new issue
Block a user