From 0d7ec9c5de8c98eb4100a1abf19077f7d0330ca2 Mon Sep 17 00:00:00 2001 From: Evan Hahn Date: Sat, 25 May 2024 11:18:07 -0500 Subject: [PATCH] CSP: clean up `getDefaultDirectives` 1. `getDefaultDirectives` is now faster, avoiding `structuredClone`. 2. We don't need to call `getDefaultDirectives`. --- middlewares/content-security-policy/index.ts | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/middlewares/content-security-policy/index.ts b/middlewares/content-security-policy/index.ts index 38cc436..dbef7c6 100644 --- a/middlewares/content-security-policy/index.ts +++ b/middlewares/content-security-policy/index.ts @@ -39,10 +39,7 @@ interface ContentSecurityPolicy { const dangerouslyDisableDefaultSrc = Symbol("dangerouslyDisableDefaultSrc"); -const DEFAULT_DIRECTIVES: Record< - string, - Iterable -> = { +const DEFAULT_DIRECTIVES: Record = { "default-src": ["'self'"], "base-uri": ["'self'"], "font-src": ["'self'", "https:", "data:"], @@ -68,7 +65,19 @@ const SHOULD_BE_QUOTED: ReadonlySet = new Set([ "wasm-unsafe-eval", ]); -const getDefaultDirectives = () => structuredClone(DEFAULT_DIRECTIVES); +const getDefaultDirectives = (): Record< + string, + Iterable +> => { + const result: Record< + string, + Iterable + > = {}; + for (const [key, value] of Object.entries(DEFAULT_DIRECTIVES)) { + result[key] = value.concat(); + } + return result; +}; const dashify = (str: string): string => str.replace(/[A-Z]/g, (capitalLetter) => "-" + capitalLetter.toLowerCase()); @@ -93,9 +102,7 @@ const invalidDirectiveValueError = (directiveName: string): Error => function normalizeDirectives( options: Readonly, ): NormalizedDirectives { - const defaultDirectives = getDefaultDirectives(); - - const { useDefaults = true, directives: rawDirectives = defaultDirectives } = + const { useDefaults = true, directives: rawDirectives = DEFAULT_DIRECTIVES } = options; const result: NormalizedDirectives = new Map(); @@ -176,7 +183,7 @@ function normalizeDirectives( } if (useDefaults) { - Object.entries(defaultDirectives).forEach( + Object.entries(DEFAULT_DIRECTIVES).forEach( ([defaultDirectiveName, defaultDirectiveValue]) => { if ( !result.has(defaultDirectiveName) &&