diff --git a/.changeset/loud-files-tap.md b/.changeset/loud-files-tap.md new file mode 100644 index 000000000..fbc677952 --- /dev/null +++ b/.changeset/loud-files-tap.md @@ -0,0 +1,5 @@ +--- +'gitbook': patch +--- + +Allow only good values for theme query parameter. Avoid having a 500 error when we pass an invalid value. diff --git a/packages/gitbook/src/lib/api.ts b/packages/gitbook/src/lib/api.ts index 94b819b18..52ffefd39 100644 --- a/packages/gitbook/src/lib/api.ts +++ b/packages/gitbook/src/lib/api.ts @@ -876,6 +876,18 @@ export async function getSiteData( }; } +/** + * Validate that the customization settings passed are valid. + */ +export function validateSerializedCustomization(raw: string): boolean { + try { + rison.decode_object(raw); + return true; + } catch { + return false; + } +} + /** * Get the customization settings for a space from the API. */ diff --git a/packages/gitbook/src/middleware.ts b/packages/gitbook/src/middleware.ts index e435ca3d7..7378145fc 100644 --- a/packages/gitbook/src/middleware.ts +++ b/packages/gitbook/src/middleware.ts @@ -1,10 +1,11 @@ -import { ContentAPITokenPayload, GitBookAPI } from '@gitbook/api'; +import { ContentAPITokenPayload, CustomizationThemeMode, GitBookAPI } from '@gitbook/api'; import { setTag, setContext } from '@sentry/nextjs'; import assertNever from 'assert-never'; import jwt from 'jsonwebtoken'; import type { ResponseCookie } from 'next/dist/compiled/@edge-runtime/cookies'; import { NextResponse, NextRequest } from 'next/server'; import hash from 'object-hash'; +import rison from 'rison'; import { PublishedContentWithCache, @@ -17,6 +18,7 @@ import { DEFAULT_API_ENDPOINT, getPublishedContentSite, getSiteData, + validateSerializedCustomization, } from '@/lib/api'; import { race } from '@/lib/async'; import { buildVersion } from '@/lib/build'; @@ -259,12 +261,12 @@ export async function middleware(request: NextRequest) { } const customization = url.searchParams.get('customization'); - if (customization) { + if (customization && validateSerializedCustomization(customization)) { headers.set('x-gitbook-customization', customization); } const theme = url.searchParams.get('theme'); - if (theme) { + if (theme === CustomizationThemeMode.Dark || theme === CustomizationThemeMode.Light) { headers.set('x-gitbook-theme', theme); }