diff --git a/.changeset/fix-foreach-script-template-sanitization.md b/.changeset/fix-foreach-script-template-sanitization.md new file mode 100644 index 000000000..a883fa74b --- /dev/null +++ b/.changeset/fix-foreach-script-template-sanitization.md @@ -0,0 +1,8 @@ +--- +'@tko/binding.foreach': patch +--- + +Fix `makeTemplateNode` bypassing HTML sanitization for `").appendTo(document.body) + $template.text('
  • ') + + try { + options.templateSizeLimit = 10 + + assert.throws(function () { + applyBindings(['G1'], target[0]) + }, /Template is too long/) + } finally { + options.templateSizeLimit = originalTemplateSizeLimit + $template.remove() + } + }) + + it('rejects nested script markup in named ").appendTo(document.body) + $template.text('
  • ') + + try { + options.allowScriptTagsInTemplates = false + + assert.throws(function () { + applyBindings(['G1'], target[0]) + }, /Script-tag in template detected/) + } finally { + options.allowScriptTagsInTemplates = originalAllowScriptTagsInTemplates + $template.remove() + } + }) + + it('sanitizes named ").appendTo(document.body) + const list = ['G1'] + let sanitizedHtml = '' + $template.text('
  • ') + + try { + options.sanitizeHtmlTemplate = function (html: string) { + sanitizedHtml = html + return html.replace('
  • ', function () { const target = $('') const list = ['H1', 'H2'] diff --git a/packages/binding.foreach/src/foreach.ts b/packages/binding.foreach/src/foreach.ts index 72ef35ce6..550cc8909 100644 --- a/packages/binding.foreach/src/foreach.ts +++ b/packages/binding.foreach/src/foreach.ts @@ -5,7 +5,15 @@ // Employing sound techniques to make a faster Knockout foreach binding. // -------- -import { arrayForEach, cleanNode, options, virtualElements, domData, domNodeIsContainedBy } from '@tko/utils' +import { + arrayForEach, + cleanNode, + options, + virtualElements, + domData, + domNodeIsContainedBy, + parseHtmlForTemplateNodes +} from '@tko/utils' import { isObservable, unwrap, observable } from '@tko/observable' @@ -13,8 +21,6 @@ import type { ObservableArray } from '@tko/observable' import { contextFor, applyBindingsToDescendants, AsyncBindingHandler } from '@tko/bind' -import type { AllBindings } from '@tko/bind' - // Utilities const MAX_LIST_SIZE = Number.MAX_SAFE_INTEGER @@ -56,8 +62,7 @@ function makeTemplateNode(sourceNode) { // For e.g.