From e3d3408e4a24d5e71bc720efb72e8ebee5078712 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 20 Jun 2022 13:29:08 -0400 Subject: [PATCH 1/2] feat: catch invalid requests --- .../server/__tests__/is-invalid-uri.test.ts | 14 ++++++++++++++ packages/docs-page/server/index.ts | 17 +++++++++++++++++ packages/docs-page/server/is-invalid-uri.ts | 12 ++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 packages/docs-page/server/__tests__/is-invalid-uri.test.ts create mode 100644 packages/docs-page/server/is-invalid-uri.ts diff --git a/packages/docs-page/server/__tests__/is-invalid-uri.test.ts b/packages/docs-page/server/__tests__/is-invalid-uri.test.ts new file mode 100644 index 000000000..8d6c409b7 --- /dev/null +++ b/packages/docs-page/server/__tests__/is-invalid-uri.test.ts @@ -0,0 +1,14 @@ +import { isInvalidURI } from '../is-invalid-uri' + +describe('isInvalidURI', () => { + it.each([ + ['/docs/upgrade', false], + ['foo/bar%23anchor', false], + [ + "/docs/upgrade%25'%20AND%202*3*8=6*8%20AND%20'zVVl'!='zVVl%25/upgrade-specific", + true, + ], + ])('given `%s`, returns `%s`', (a, expected) => { + expect(isInvalidURI(a)).toBe(expected) + }) +}) diff --git a/packages/docs-page/server/index.ts b/packages/docs-page/server/index.ts index d81ed5c11..15ab424c1 100644 --- a/packages/docs-page/server/index.ts +++ b/packages/docs-page/server/index.ts @@ -3,6 +3,8 @@ import { ContentApiError } from '../content-api' import FileSystemLoader from './loaders/file-system' import RemoteContentLoader from './loaders/remote-content' import { DataLoader } from './loaders/types' +import { isInvalidURI } from './is-invalid-uri' +import { DEFAULT_PARAM_ID } from './consts' // We currently export most utilities individually, // since we have cases such as Packer remote plugin docs @@ -67,6 +69,21 @@ export function getStaticGenerationFunctions( } }, getStaticProps: async (ctx) => { + const pathParams = ctx.params?.[opts.paramId || DEFAULT_PARAM_ID] + + if (pathParams) { + if (Array.isArray(pathParams)) { + const path = pathParams.join('/') + if (isInvalidURI(path)) { + return { notFound: true } + } + } else if (typeof pathParams === 'string') { + if (isInvalidURI(pathParams)) { + return { notFound: true } + } + } + } + try { const props = await loader.loadStaticProps(ctx) return { diff --git a/packages/docs-page/server/is-invalid-uri.ts b/packages/docs-page/server/is-invalid-uri.ts new file mode 100644 index 000000000..a34e4ae10 --- /dev/null +++ b/packages/docs-page/server/is-invalid-uri.ts @@ -0,0 +1,12 @@ +/** matches any whitespace or % */ +const RE = /(\s|%)/gi +/** decodes a URI once, and returns if it is invalid */ +export const isInvalidURI = (uri: string) => { + try { + const res = decodeURIComponent(uri) + return !!res.match(RE) + } catch (err: any) { + console.warn(err.message, uri) + return true + } +} From 86425245bf37142ff47910d1ace3ed0ded2aea2f Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 20 Jun 2022 13:30:03 -0400 Subject: [PATCH 2/2] chore: changeset --- .changeset/dirty-pears-divide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/dirty-pears-divide.md diff --git a/.changeset/dirty-pears-divide.md b/.changeset/dirty-pears-divide.md new file mode 100644 index 000000000..dd67e8a19 --- /dev/null +++ b/.changeset/dirty-pears-divide.md @@ -0,0 +1,5 @@ +--- +'@hashicorp/react-docs-page': minor +--- + +catches invalid request and 404s