|
1 | 1 | import { UmbTiptapExtensionApiBase } from '../tiptap-extension-api-base.js'; |
2 | 2 | import { umbRteBlock, umbRteBlockInline, umbRteBlockPaste } from './block.tiptap-extension.js'; |
3 | 3 | import { distinctUntilChanged } from '@umbraco-cms/backoffice/external/rxjs'; |
| 4 | +import { DOMPurify } from '@umbraco-cms/backoffice/external/dompurify'; |
4 | 5 | import { UmbId } from '@umbraco-cms/backoffice/id'; |
5 | 6 | import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; |
6 | 7 | import { UMB_BLOCK_RTE_DATA_CONTENT_KEY } from '@umbraco-cms/backoffice/rte'; |
@@ -50,9 +51,15 @@ export default class UmbTiptapBlockElementApi extends UmbTiptapExtensionApiBase |
50 | 51 | return false; |
51 | 52 | } |
52 | 53 |
|
53 | | - // Parse the HTML |
| 54 | + // Sanitize the HTML immediately to prevent XSS attacks while preserving RTE block elements |
| 55 | + const sanitizedHtml = DOMPurify.sanitize(html, { |
| 56 | + ADD_TAGS: ['umb-rte-block', 'umb-rte-block-inline'], |
| 57 | + ADD_ATTR: [UMB_BLOCK_RTE_DATA_CONTENT_KEY], |
| 58 | + }); |
| 59 | + |
| 60 | + // Parse the sanitized HTML |
54 | 61 | const parser = new DOMParser(); |
55 | | - const doc = parser.parseFromString(html, 'text/html'); |
| 62 | + const doc = parser.parseFromString(sanitizedHtml, 'text/html'); |
56 | 63 | const blockElements = doc.querySelectorAll('umb-rte-block, umb-rte-block-inline'); |
57 | 64 |
|
58 | 65 | if (blockElements.length === 0) { |
@@ -121,9 +128,8 @@ export default class UmbTiptapBlockElementApi extends UmbTiptapExtensionApiBase |
121 | 128 | return false; |
122 | 129 | } |
123 | 130 |
|
124 | | - // Get the modified HTML and insert it |
125 | | - const modifiedHtml = doc.body.innerHTML; |
126 | | - this._editor.commands.insertContent(modifiedHtml, { parseOptions: { preserveWhitespace: 'full' } }); |
| 131 | + // Insert the modified HTML (already sanitized at function entry) |
| 132 | + this._editor.commands.insertContent(doc.body.innerHTML, { parseOptions: { preserveWhitespace: 'full' } }); |
127 | 133 |
|
128 | 134 | // Return true to indicate we handled the paste |
129 | 135 | return true; |
|
0 commit comments