From 256f2e4ecae72ed2db07ae63fc78400c6ebda6d1 Mon Sep 17 00:00:00 2001 From: kobezzza Date: Mon, 15 Jul 2024 16:32:06 +0300 Subject: [PATCH] fix: xss --- .../elements/abstract/engines/ssr/const.ts | 35 +++++++++++++++++++ .../elements/abstract/engines/ssr/index.ts | 14 ++++---- .../elements/title/engines/ssr/index.ts | 6 ++-- 3 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 src/core/page-meta-data/elements/abstract/engines/ssr/const.ts diff --git a/src/core/page-meta-data/elements/abstract/engines/ssr/const.ts b/src/core/page-meta-data/elements/abstract/engines/ssr/const.ts new file mode 100644 index 0000000000..2a28b224fb --- /dev/null +++ b/src/core/page-meta-data/elements/abstract/engines/ssr/const.ts @@ -0,0 +1,35 @@ +/*! + * V4Fire Client Core + * https://github.com/V4Fire/Client + * + * Released under the MIT license + * https://github.com/V4Fire/Client/blob/master/LICENSE + */ + +export const allowedTags = { + meta: [ + 'meta', + 'name', + 'content', + 'http-equiv', + 'charset', + 'property' + ], + + link: [ + 'href', + 'rel', + 'type', + 'media', + 'sizes', + 'as', + 'crossorigin', + 'integrity', + 'title', + 'charset', + 'hreflang', + 'referrerpolicy' + ], + + title: [] +}; diff --git a/src/core/page-meta-data/elements/abstract/engines/ssr/index.ts b/src/core/page-meta-data/elements/abstract/engines/ssr/index.ts index d7a32a6317..5f844ddf46 100644 --- a/src/core/page-meta-data/elements/abstract/engines/ssr/index.ts +++ b/src/core/page-meta-data/elements/abstract/engines/ssr/index.ts @@ -11,20 +11,22 @@ import { sanitize } from 'core/html/xss'; import type { Engine } from 'core/page-meta-data/elements/abstract/engines/interface'; import type { AbstractElement } from 'core/page-meta-data/elements'; +import { allowedTags } from 'core/page-meta-data/elements/abstract/engines/ssr/const'; + +export * from 'core/page-meta-data/elements/abstract/engines/ssr/const'; + export class SSREngine implements Engine { /** {@link Engine.render} */ render(_element: AbstractElement, tag: string, attrs: Dictionary): string { - const keys = Object.keys(attrs); - - const attrsString = keys - .map((key) => `${key}="${attrs[key]}"`) + const attrsString = Object.entries(attrs) + .map(([key, val]) => `${key}="${val}"`) .join(' '); return sanitize(`<${tag} ${attrsString} />`, { RETURN_DOM: true, WHOLE_DOCUMENT: true, - ADD_TAGS: [tag], - ALLOWED_ATTR: keys + ADD_TAGS: allowedTags[tag] != null ? [tag] : [], + ALLOWED_ATTR: allowedTags[tag] ?? [] }).querySelector(tag)!.outerHTML; } diff --git a/src/core/page-meta-data/elements/title/engines/ssr/index.ts b/src/core/page-meta-data/elements/title/engines/ssr/index.ts index 3aeee2f5f1..4bab194365 100644 --- a/src/core/page-meta-data/elements/title/engines/ssr/index.ts +++ b/src/core/page-meta-data/elements/title/engines/ssr/index.ts @@ -9,15 +9,15 @@ import { sanitize } from 'core/html/xss'; import type { AbstractElement } from 'core/page-meta-data/elements'; -import { SSREngine } from 'core/page-meta-data/elements/abstract/engines'; +import { SSREngine, allowedTags } from 'core/page-meta-data/elements/abstract/engines'; export class SSRTitleEngine extends SSREngine { override render(_element: AbstractElement, tag: string, attrs: Dictionary): string { return sanitize(`<${tag}>${attrs.text ?? ''}`, { RETURN_DOM: true, WHOLE_DOCUMENT: true, - ADD_TAGS: [tag], - ALLOWED_ATTR: [] + ADD_TAGS: tag === 'title' ? [tag] : [], + ALLOWED_ATTR: allowedTags[tag] ?? [] }).querySelector(tag)!.outerHTML; } }