From c4d888f0605fe9467a407ae70f910c7f18707623 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 8 Sep 2019 23:47:28 -0700 Subject: [PATCH] Whitelist tags/attributes instead of allow-all (#3657) --- src/resources/markdown_worker.ts | 39 +++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/resources/markdown_worker.ts b/src/resources/markdown_worker.ts index ec06680ce0..fd2ee988e3 100644 --- a/src/resources/markdown_worker.ts +++ b/src/resources/markdown_worker.ts @@ -2,9 +2,12 @@ import marked from "marked"; // @ts-ignore import filterXSS from "xss"; -const allowedSvgTags = ["svg", "path"]; +interface WhiteList { + [tag: string]: string[]; +} -const allowedTag = (tag: string) => tag === "ha-icon"; +let whiteListNormal: WhiteList | undefined; +let whiteListSvg: WhiteList | undefined; export const renderMarkdown = ( content: string, @@ -13,10 +16,30 @@ export const renderMarkdown = ( // Do not allow SVG on untrusted content, it allows XSS. allowSvg?: boolean; } = {} -) => - filterXSS(marked(content, markedOptions), { - onIgnoreTag: hassOptions.allowSvg - ? (tag, html) => - allowedTag(tag) || allowedSvgTags.includes(tag) ? html : null - : (tag, html) => (allowedTag(tag) ? html : null), +) => { + if (!whiteListNormal) { + whiteListNormal = { + ...filterXSS.whiteList, + "ha-icon": ["icon"], + }; + } + + let whiteList: WhiteList | undefined; + + if (hassOptions.allowSvg) { + if (!whiteListSvg) { + whiteListSvg = { + ...whiteListNormal, + svg: ["xmlns", "height", "width"], + path: ["transform", "stroke", "d"], + }; + } + whiteList = whiteListSvg; + } else { + whiteList = whiteListNormal; + } + + return filterXSS(marked(content, markedOptions), { + whiteList, }); +};