diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb
index dd5a63a5fc..fdad5f4814 100644
--- a/app/models/enterprise.rb
+++ b/app/models/enterprise.rb
@@ -247,6 +247,11 @@ class Enterprise < ApplicationRecord
count(distinct: true)
end
+ # Remove any unsupported HTML.
+ def long_description=(html)
+ super(HtmlSanitizer.sanitize(html))
+ end
+
def contact
contact = users.where(enterprise_roles: { receives_notifications: true }).first
contact || owner
diff --git a/app/services/html_sanitizer.rb b/app/services/html_sanitizer.rb
new file mode 100644
index 0000000000..4f2e44e0ab
--- /dev/null
+++ b/app/services/html_sanitizer.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+# Keeps only allowed HTML.
+#
+# We store some rich text as HTML in attributes of models like Enterprise.
+# We offer an editor which supports certain tags but you can't insert just any
+# HTML, which would be dangerous.
+class HtmlSanitizer
+ def self.sanitize(html)
+ @sanitizer ||= Rails::HTML5::SafeListSanitizer.new
+ @sanitizer.sanitize(
+ html, tags: %w[h1 h2 h3 h4 p b i u a], attributes: %w[href target],
+ )
+ end
+end
diff --git a/spec/models/enterprise_spec.rb b/spec/models/enterprise_spec.rb
index 300dd84ccb..b853031c23 100644
--- a/spec/models/enterprise_spec.rb
+++ b/spec/models/enterprise_spec.rb
@@ -398,6 +398,13 @@ RSpec.describe Enterprise do
end
end
+ describe "serialisation" do
+ it "sanitises HTML in long_description" do
+ subject.long_description = "Hello dearest monster."
+ expect(subject.long_description).to eq "Hello alert dearest monster."
+ end
+ end
+
describe "callbacks" do
it "restores permalink to original value when it is changed and invalid" do
e1 = create(:enterprise, permalink: "taken")
diff --git a/spec/services/html_sanitizer_spec.rb b/spec/services/html_sanitizer_spec.rb
new file mode 100644
index 0000000000..7f238ab733
--- /dev/null
+++ b/spec/services/html_sanitizer_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+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!"
+ end
+
+ it "keeps supported tags" do
+ html = "Hello alert!"
+ expect(subject.sanitize(html))
+ .to eq "Hello alert!"
+ end
+
+ it "keeps supported attributes" do
+ html = 'Hello alert!'
+ expect(subject.sanitize(html))
+ .to eq 'Hello alert!'
+ end
+
+ it "removes unsupported attributes" do
+ html = 'Hello alert!'
+ expect(subject.sanitize(html))
+ .to eq 'Hello alert!'
+ end
+
+ it "removes dangerous attribute values" do
+ html = 'Hello you!'
+ expect(subject.sanitize(html))
+ .to eq 'Hello you!'
+ end
+end