Bug description
POST /~gitbook/revalidate fails open when GITBOOK_SECRET is not configured: the signature check is skipped and cache revalidation runs for any caller. In packages/gitbook/src/lib/routes.ts:16, if (GITBOOK_SECRET) { ... } falls through to the handler when the secret is unset (fail-open), and revalidate/route.ts:29 calls revalidateTag for every tag in the request body.
This is inconsistent with the sibling endpoint force-revalidate.ts, which fails closed (returns 403 Revalidation is disabled) without a secret. Cloud deployments aren't affected (the secret is always injected from 1Password); this only matters for self-hosted setups that don't set GITBOOK_SECRET. Since there's no .env.example and no docs marking it as required, that's easy to miss.
How to reproduce
- Run a self-hosted instance without
GITBOOK_SECRET.
- POST to the endpoint with no signature header:
curl -i -X POST http://localhost:3000/~gitbook/revalidate \
-H 'Content-Type: application/json' \
-d '{"tags":["space:00000000-0000-0000-0000-000000000000"]}'
- Expected (consistent with
force-revalidate.ts): 403 Revalidation is disabled — actual: 200 {"success":true}.
Additional context
- Effect: an unauthenticated caller can force cache revalidation for known/guessable tags (
space:<id>, space:<id>:revision:<rev>, integration:<id>, see packages/cache-tags), causing origin load. No data exposure or code execution.
- Relevant code:
routes.ts:16, revalidate/route.ts:29, middleware.ts:64, globals.ts:133.
- Suggested fix: fail closed when
GITBOOK_SECRET is missing (return 403/disable revalidation), and document it as required (e.g. add an .env.example).
Bug description
POST /~gitbook/revalidatefails open whenGITBOOK_SECRETis not configured: the signature check is skipped and cache revalidation runs for any caller. Inpackages/gitbook/src/lib/routes.ts:16,if (GITBOOK_SECRET) { ... }falls through to the handler when the secret is unset (fail-open), andrevalidate/route.ts:29callsrevalidateTagfor every tag in the request body.This is inconsistent with the sibling endpoint
force-revalidate.ts, which fails closed (returns403 Revalidation is disabled) without a secret. Cloud deployments aren't affected (the secret is always injected from 1Password); this only matters for self-hosted setups that don't setGITBOOK_SECRET. Since there's no.env.exampleand no docs marking it as required, that's easy to miss.How to reproduce
GITBOOK_SECRET.force-revalidate.ts):403 Revalidation is disabled— actual:200 {"success":true}.Additional context
space:<id>,space:<id>:revision:<rev>,integration:<id>, seepackages/cache-tags), causing origin load. No data exposure or code execution.routes.ts:16,revalidate/route.ts:29,middleware.ts:64,globals.ts:133.GITBOOK_SECRETis missing (return403/disable revalidation), and document it as required (e.g. add an.env.example).