diff --git a/coffee/lib/abstract-chosen.coffee b/coffee/lib/abstract-chosen.coffee index d53c968fb81..e15282bee53 100644 --- a/coffee/lib/abstract-chosen.coffee +++ b/coffee/lib/abstract-chosen.coffee @@ -51,7 +51,7 @@ class AbstractChosen choice_label: (item) -> if @include_group_label_in_selected and item.group_label? - "#{item.group_label}#{item.html}" + "#{this.escape_html(item.group_label)}#{item.html}" else item.html diff --git a/spec/jquery/bugfixes.spec.coffee b/spec/jquery/bugfixes.spec.coffee new file mode 100644 index 00000000000..a55647717bd --- /dev/null +++ b/spec/jquery/bugfixes.spec.coffee @@ -0,0 +1,30 @@ +describe "Bugfixes", -> + it "https://github.com/harvesthq/chosen/issues/2996 - XSS Vulnerability with `include_group_label_in_selected: true`", -> + tmpl = " + + " + + div = $("
").html(tmpl) + select = div.find("select") + + select.chosen + include_group_label_in_selected: true + + # open the drop + container = div.find(".chosen-container") + container.trigger("mousedown") + + xss_option = container.find(".active-result").last() + expect(xss_option.html()).toBe "an xss option" + + # trigger the selection of the xss option + xss_option.trigger("mouseup") + + # make sure the script tags are escaped correctly + label_html = container.find("a.chosen-single").html() + expect(label_html).toContain('</script><script>console.log(1)</script>') diff --git a/spec/proto/bugfixes.spec.coffee b/spec/proto/bugfixes.spec.coffee new file mode 100644 index 00000000000..004285de502 --- /dev/null +++ b/spec/proto/bugfixes.spec.coffee @@ -0,0 +1,32 @@ +describe "Bugfixes", -> + it "https://github.com/harvesthq/chosen/issues/2996 - XSS Vulnerability with `include_group_label_in_selected: true`", -> + tmpl = " + + " + div = new Element("div") + document.body.insert(div) + div.innerHTML = tmpl + + select = div.down("select") + new Chosen select, + include_group_label_in_selected: true + + # open the drop + container = div.down(".chosen-container") + simulant.fire(container, "mousedown") # open the drop + + xss_option = container.select(".active-result").last() + expect(xss_option.innerHTML).toBe "an xss option" + + # trigger the selection of the xss option + simulant.fire(xss_option, "mouseup") + + # make sure the script tags are escaped correctly + label_html = container.down("a.chosen-single").innerHTML + expect(label_html).toContain('</script><script>console.log(1)</script>') +