diff --git a/app/models/spree/product.rb b/app/models/spree/product.rb index d760c329ec..1f79ebf95c 100755 --- a/app/models/spree/product.rb +++ b/app/models/spree/product.rb @@ -304,6 +304,16 @@ module Spree ) end + # Remove any unsupported HTML. + def description + HtmlSanitizer.sanitize(super) + end + + # Remove any unsupported HTML. + def description=(html) + super(HtmlSanitizer.sanitize(html)) + end + private def update_units diff --git a/app/services/html_sanitizer.rb b/app/services/html_sanitizer.rb index df3c608219..84d78f6f5c 100644 --- a/app/services/html_sanitizer.rb +++ b/app/services/html_sanitizer.rb @@ -6,10 +6,16 @@ # We offer an editor which supports certain tags but you can't insert just any # HTML, which would be dangerous. class HtmlSanitizer + # div is required by Trix editor + ALLOWED_TAGS = %w[h1 h2 h3 h4 div p br b i u a strong em del pre blockquote ul ol li hr + figure].freeze + ALLOWED_ATTRIBUTES = %w[href target].freeze + ALLOWED_TRIX_DATA_ATTRIBUTES = %w[data-trix-attachment].freeze + def self.sanitize(html) @sanitizer ||= Rails::HTML5::SafeListSanitizer.new @sanitizer.sanitize( - html, tags: %w[h1 h2 h3 h4 p br b i u a], attributes: %w[href target], + html, tags: ALLOWED_TAGS, attributes: (ALLOWED_ATTRIBUTES + ALLOWED_TRIX_DATA_ATTRIBUTES) ) end end diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index 15667125c3..993b1cb833 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -748,6 +748,18 @@ module Spree expect(e.variants.reload).to be_empty end end + + describe "serialisation" do + it "sanitises HTML in description" do + subject.description = "Hello dearest monster." + expect(subject.description).to eq "Hello alert dearest monster." + end + + it "sanitises existing HTML in description" do + subject[:description] = "Hello dearest monster." + expect(subject.description).to eq "Hello alert dearest monster." + end + end end RSpec.describe "product import" do diff --git a/spec/services/html_sanitizer_spec.rb b/spec/services/html_sanitizer_spec.rb index c98d695b35..bda9eb2188 100644 --- a/spec/services/html_sanitizer_spec.rb +++ b/spec/services/html_sanitizer_spec.rb @@ -5,33 +5,97 @@ require 'spec_helper' RSpec.describe HtmlSanitizer do subject { described_class } - it "removes dangerous tags" do - html = "Hello !" - expect(subject.sanitize(html)) - .to eq "Hello alert!" + context "when HTML has supported tags" do + it "keeps supported regular tags" do + supported_tags = %w[h1 h2 h3 h4 div p b i u a strong em del pre blockquote ul ol li figure] + supported_tags.each do |tag| + html = "<#{tag}>Content#{tag}>" + sanitized_html = subject.sanitize(html) + expect(sanitized_html).to eq(html), "Expected '#{tag}' to be preserved." + end + end + + it "keeps supported void tags" do + supported_tags = %w[br hr] + supported_tags.each do |tag| + html = "<#{tag}>" + sanitized_html = subject.sanitize(html) + expect(sanitized_html).to eq(html), "Expected '#{tag}' to be preserved." + end + end + + it "handles nested tags" do + html = '