From b1b9645872c8db50458371488c4fcb8eaa1b4105 Mon Sep 17 00:00:00 2001 From: undefined Date: Mon, 20 May 2024 01:07:16 +0800 Subject: [PATCH] ui: update cssFilter --- .../ui-default/backendlib/markdown-it-xss.ts | 151 ++++++++---------- packages/ui-default/package.json | 1 + 2 files changed, 65 insertions(+), 87 deletions(-) diff --git a/packages/ui-default/backendlib/markdown-it-xss.ts b/packages/ui-default/backendlib/markdown-it-xss.ts index 273cf2905..bcf8e1305 100644 --- a/packages/ui-default/backendlib/markdown-it-xss.ts +++ b/packages/ui-default/backendlib/markdown-it-xss.ts @@ -1,3 +1,4 @@ +import { FilterCSS } from 'cssfilter'; import { escapeAttrValue, FilterXSS, safeAttrValue } from 'xss'; const stack = []; @@ -33,15 +34,29 @@ const tagCheck = new FilterXSS({ }, }); -export const xss = new FilterXSS({ +const cssFilterOptions = { + whiteList: { + 'font-size': true, + 'font-family': true, + 'text-align': true, + 'text-indent': true, + 'margin-left': true, + position: /relative/, + padding: true, + height: true, + width: true, + color: true, + }, +}; + +const CssFilter = new FilterXSS(cssFilterOptions); + +const commonRules = { whiteList: { a: ['target', 'href', 'title'], abbr: ['title'], address: [], - area: ['shape', 'coords', 'href', 'alt'], - article: [], aside: [], - audio: ['autoplay', 'controls', 'loop', 'preload', 'src'], b: [], bdi: ['dir'], bdo: ['dir'], @@ -52,40 +67,57 @@ export const xss = new FilterXSS({ center: [], cite: [], code: ['class'], + del: ['datetime'], + div: ['id', 'class'], + dl: [], + em: [], + font: ['color', 'size', 'face'], + header: [], + i: [], + ins: ['datetime'], + mark: [], + ol: [], + p: ['align', 'style'], + pre: [], + s: [], + small: [], + span: ['class', 'style'], + sub: [], + sup: [], + strong: ['id'], + tt: [], + u: [], + var: [], + }, + css: false, + allowCommentTag: false, + stripIgnoreTag: true, + stripIgnoreTagBody: ['script', 'semantics'], +}; + +export const xss = new FilterXSS({ + ...commonRules, + whiteList: { + ...commonRules.whiteList, + area: ['shape', 'coords', 'href', 'alt'], + article: [], + audio: ['autoplay', 'controls', 'loop', 'preload', 'src'], col: ['align', 'valign', 'span', 'width'], colgroup: ['align', 'valign', 'span', 'width'], dd: [], - del: ['datetime'], details: ['open'], - div: ['id', 'class'], - dl: [], dt: [], - em: [], - font: ['color', 'size', 'face'], h1: ['id'], h2: ['id', 'class'], h3: ['id'], h4: ['id'], h5: ['id'], h6: ['id'], - header: [], hr: [], - i: [], img: ['src', 'alt', 'title', 'width', 'height'], - ins: ['datetime'], li: [], - mark: [], - ol: [], - p: ['align', 'style'], - pre: [], - s: [], section: [], - small: [], - span: ['class', 'style'], - sub: [], summary: [], - sup: [], - strong: ['id'], table: ['width', 'border', 'align', 'valign'], tbody: ['align', 'valign'], td: ['width', 'rowspan', 'colspan', 'align', 'valign', 'bgcolor'], @@ -93,84 +125,29 @@ export const xss = new FilterXSS({ th: ['width', 'rowspan', 'colspan', 'align', 'valign'], thead: ['align', 'valign'], tr: ['rowspan', 'align', 'valign'], - tt: [], - u: [], ul: [], - var: [], video: ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width'], }, - css: { - whiteList: { - 'font-size': true, - 'font-family': true, - 'text-align': true, - 'text-indent': true, - 'margin-left': true, - color: true, - }, - }, - allowCommentTag: false, - stripIgnoreTagBody: ['script'], + css: cssFilterOptions, safeAttrValue(tag, name, value) { if (name === 'id') return escapeAttrValue(`xss-id-${value}`); if (name === 'class') return escapeAttrValue(value.replace(/badge/g, 'xss-badge')); - return safeAttrValue(tag, name, value, this.cssFilter); + return safeAttrValue(tag, name, value, CssFilter); + }, +}); + +const inlineCssFilter = new FilterCSS({ + whiteList: { + color: true, }, }); export const xssInline = new FilterXSS({ - whiteList: { - a: ['target', 'href', 'title'], - abbr: ['title'], - address: [], - aside: [], - b: [], - bdi: ['dir'], - bdo: ['dir'], - big: [], - blockquote: ['cite', 'class'], - br: [], - caption: [], - center: [], - cite: [], - code: ['class'], - del: ['datetime'], - div: ['id', 'class'], - dl: [], - em: [], - font: ['color', 'size', 'face'], - header: [], - i: [], - ins: ['datetime'], - mark: [], - ol: [], - p: ['align', 'style'], - pre: [], - s: [], - small: [], - span: ['class', 'style'], - sub: [], - sup: [], - strong: ['id'], - tt: [], - u: [], - var: [], - }, - css: { - whiteList: { - 'font-size': true, - 'font-family': true, - 'text-indent': true, - color: true, - }, - }, - allowCommentTag: false, - stripIgnoreTag: true, - stripIgnoreTagBody: ['script'], + ...commonRules, safeAttrValue(tag, name, value) { if (name === 'id') return escapeAttrValue(`xss-id-${value}`); if (name === 'class') return escapeAttrValue(value.replace(/badge/g, 'xss-badge')); - return safeAttrValue(tag, name, value, this.cssFilter); + return safeAttrValue(tag, name, value, inlineCssFilter); }, }); diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 267715f75..8cb5412a5 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -126,6 +126,7 @@ }, "dependencies": { "ansi_up": "^6.0.2", + "cssfilter": "^0.0.10", "esbuild": "0.18.20", "fs-extra": "^11.2.0", "js-yaml": "^4.1.0",