From 8b28c84017e2a839c6fa9f7226d3ec77e1e52cc9 Mon Sep 17 00:00:00 2001 From: Luminessa Starlight <10436679+samsch@users.noreply.github.com> Date: Thu, 17 Apr 2025 12:56:09 -0400 Subject: [PATCH] TextPanel: Allow markdown to-do checkboxes in TextPanel (#104136) TextPanel: Allow markdown to-do checkboxes Fixes #95054 --- .../grafana-data/src/text/markdown.test.ts | 16 +++++++++++++ .../grafana-data/src/text/sanitize.test.ts | 24 ++++++++++++++++++- packages/grafana-data/src/text/sanitize.ts | 8 ++++++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/packages/grafana-data/src/text/markdown.test.ts b/packages/grafana-data/src/text/markdown.test.ts index 7784169b2ad..d596212baea 100644 --- a/packages/grafana-data/src/text/markdown.test.ts +++ b/packages/grafana-data/src/text/markdown.test.ts @@ -23,6 +23,22 @@ describe('Markdown wrapper', () => { ); }); + it('should allow markdown todo checkbox inputs', () => { + const str = renderTextPanelMarkdown(`- [ ] unchecked +- [x] checked`); + expect(str).toMatch(//); + expect(str).toMatch(//); + }); + + it('should sanitize arbitrary input elements', () => { + const str = renderTextPanelMarkdown(` + + + + `); + expect(str).not.toMatch(/ { const str = renderTextPanelMarkdown(''); expect(str).toBe('<script>alert()</script>'); diff --git a/packages/grafana-data/src/text/sanitize.test.ts b/packages/grafana-data/src/text/sanitize.test.ts index 6aafd2e6afc..37d616055a7 100644 --- a/packages/grafana-data/src/text/sanitize.test.ts +++ b/packages/grafana-data/src/text/sanitize.test.ts @@ -1,6 +1,6 @@ import { sanitizeTextPanelContent, sanitizeUrl, sanitize } from './sanitize'; -describe('Sanitize wrapper', () => { +describe('sanitizeTextPanelContent', () => { it('should allow whitelisted styles in text panel', () => { const html = '
'; @@ -9,6 +9,28 @@ describe('Sanitize wrapper', () => { '
' ); }); + + it('should escape xss payload', () => { + const html = ''; + const str = sanitizeTextPanelContent(html); + expect(str).toBe('<script>alert(1)</script>'); + }); + + it('should allow markdown generated unstyled disabled checkbox inputs', () => { + const str = sanitizeTextPanelContent(` +`); + expect(str).toMatch(//); + expect(str).toMatch(//); + }); + + it('should sanitize arbitrary input elements', () => { + const str = sanitizeTextPanelContent(` + + + + `); + expect(str).not.toMatch(/ { diff --git a/packages/grafana-data/src/text/sanitize.ts b/packages/grafana-data/src/text/sanitize.ts index eb8c3804e6e..c2be3a917ee 100644 --- a/packages/grafana-data/src/text/sanitize.ts +++ b/packages/grafana-data/src/text/sanitize.ts @@ -13,7 +13,7 @@ XSSWL.iframe = ['src', 'width', 'height']; const sanitizeTextPanelWhitelist = new xss.FilterXSS({ // Add sandbox attribute to iframe tags if an attribute is allowed. - onTagAttr: function (tag, name, value, isWhiteAttr) { + onTagAttr(tag, name, value, isWhiteAttr) { if (tag === 'iframe') { return isWhiteAttr ? ` ${name}="${xss.escapeAttrValue(sanitizeUrl(value))}" sandbox credentialless referrerpolicy=no-referrer` @@ -21,6 +21,12 @@ const sanitizeTextPanelWhitelist = new xss.FilterXSS({ } return; }, + onTag(tag, html, options) { + if (html === '' || html === '') { + return html; + } + return; + }, whiteList: XSSWL, css: { whiteList: {