Sanitise HTML in long description of enterprise

This happens only on assignment. We still need to migrate existing data.
This commit is contained in:
Maikel Linke
2024-05-10 12:36:49 +10:00
parent 13e4d4beb6
commit 7b4a85f7ef
4 changed files with 64 additions and 0 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -398,6 +398,13 @@ RSpec.describe Enterprise do
end
end
describe "serialisation" do
it "sanitises HTML in long_description" do
subject.long_description = "Hello <script>alert</script> dearest <b>monster</b>."
expect(subject.long_description).to eq "Hello alert dearest <b>monster</b>."
end
end
describe "callbacks" do
it "restores permalink to original value when it is changed and invalid" do
e1 = create(:enterprise, permalink: "taken")

View File

@@ -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 <script>alert</script>!"
expect(subject.sanitize(html))
.to eq "Hello alert!"
end
it "keeps supported tags" do
html = "Hello <b>alert</b>!"
expect(subject.sanitize(html))
.to eq "Hello <b>alert</b>!"
end
it "keeps supported attributes" do
html = 'Hello <a href="#focus">alert</a>!'
expect(subject.sanitize(html))
.to eq 'Hello <a href="#focus">alert</a>!'
end
it "removes unsupported attributes" do
html = 'Hello <a href="#focus" onclick="alert">alert</a>!'
expect(subject.sanitize(html))
.to eq 'Hello <a href="#focus">alert</a>!'
end
it "removes dangerous attribute values" do
html = 'Hello <a href="javascript:alert(\"boo!\")">you</a>!'
expect(subject.sanitize(html))
.to eq 'Hello <a>you</a>!'
end
end