Skip to content

Commit

Permalink
Merge pull request #12470 from mkllnk/description-html-test
Browse files Browse the repository at this point in the history
Sanitise HTML in long description of enterprise [read-only]
  • Loading branch information
filipefurtad0 committed May 15, 2024
2 parents b67eba2 + f089c0e commit a854775
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
10 changes: 10 additions & 0 deletions app/models/enterprise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,16 @@ def self.distinct_count
count(distinct: true)
end

# Remove any unsupported HTML.
def long_description
HtmlSanitizer.sanitize(super)
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
Expand Down
15 changes: 15 additions & 0 deletions app/services/html_sanitizer.rb
Original file line number Diff line number Diff line change
@@ -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 br b i u a], attributes: %w[href target],
)
end
end
12 changes: 12 additions & 0 deletions spec/models/enterprise_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,18 @@
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

it "sanitises existing 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")
Expand Down
37 changes: 37 additions & 0 deletions spec/services/html_sanitizer_spec.rb
Original file line number Diff line number Diff line change
@@ -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>! <br>How are you?"
expect(subject.sanitize(html))
.to eq "Hello <b>alert</b>! <br>How are you?"
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

0 comments on commit a854775

Please sign in to comment.