Skip to content

Commit

Permalink
Merge pull request #203 from alphagov/allow_optional_elements_to_skip…
Browse files Browse the repository at this point in the history
…_sanitisation

Allow optional elements to skip sanitisation
  • Loading branch information
edwardkerry authored Jan 14, 2021
2 parents 1e705bf + 03e9d88 commit 496036c
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 6.6.0

* Allow passed elements to be relaxed from sanitization [#203](https://github.com/alphagov/govspeak/pull/203)

## 6.5.11

* Fix issue rendering $CTA blocks before $C (PR#202)
Expand Down
3 changes: 2 additions & 1 deletion lib/govspeak.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def initialize(source, options = {})
@source = source ? source.dup : ""

@images = options.delete(:images) || []
@allowed_elements = options.delete(:allowed_elements) || []
@attachments = Array.wrap(options.delete(:attachments))
@links = Array.wrap(options.delete(:links))
@contacts = Array.wrap(options.delete(:contacts))
Expand All @@ -66,7 +67,7 @@ def initialize(source, options = {})
def to_html
@to_html ||= begin
html = if @options[:sanitize]
HtmlSanitizer.new(kramdown_doc.to_html).sanitize
HtmlSanitizer.new(kramdown_doc.to_html).sanitize(allowed_elements: @allowed_elements)
else
kramdown_doc.to_html
end
Expand Down
9 changes: 5 additions & 4 deletions lib/govspeak/html_sanitizer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,19 @@ def initialize(dirty_html, options = {})
@allowed_image_hosts = options[:allowed_image_hosts]
end

def sanitize
def sanitize(allowed_elements: [])
transformers = [TableCellTextAlignWhitelister.new]
if @allowed_image_hosts && @allowed_image_hosts.any?
transformers << ImageSourceWhitelister.new(@allowed_image_hosts)
end
Sanitize.clean(@dirty_html, Sanitize::Config.merge(sanitize_config, transformers: transformers))

Sanitize.clean(@dirty_html, Sanitize::Config.merge(sanitize_config(allowed_elements: allowed_elements), transformers: transformers))
end

def sanitize_config
def sanitize_config(allowed_elements: [])
Sanitize::Config.merge(
Sanitize::Config::RELAXED,
elements: Sanitize::Config::RELAXED[:elements] + %w[govspeak-embed-attachment govspeak-embed-attachment-link svg path],
elements: Sanitize::Config::RELAXED[:elements] + %w[govspeak-embed-attachment govspeak-embed-attachment-link svg path].concat(allowed_elements),
attributes: {
:all => Sanitize::Config::RELAXED[:attributes][:all] + %w[role aria-label],
"a" => Sanitize::Config::RELAXED[:attributes]["a"] + [:data],
Expand Down
2 changes: 1 addition & 1 deletion lib/govspeak/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Govspeak
VERSION = "6.5.11".freeze
VERSION = "6.6.0".freeze
end
5 changes: 5 additions & 0 deletions test/govspeak_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,11 @@ class GovspeakTest < Minitest::Test
assert_equal "<script>doGoodThings();</script>", document.to_html.strip
end

test "it can exclude stipulated elements from sanitization" do
document = Govspeak::Document.new("<uncommon-element>some content</uncommon-element>", allowed_elements: %w[uncommon-element])
assert_equal "<uncommon-element>some content</uncommon-element>", document.to_html.strip
end

test "identifies a Govspeak document containing malicious HTML as invalid" do
document = Govspeak::Document.new("<script>doBadThings();</script>")
refute document.valid?
Expand Down
6 changes: 6 additions & 0 deletions test/html_sanitizer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,10 @@ class HtmlSanitizerTest < Minitest::Test
assert_equal "<table><thead><tr><th>thing</th></tr></thead><tbody><tr><td>thing</td></tr></tbody></table>", Govspeak::HtmlSanitizer.new(html).sanitize
end
end

test "excludes specified elements from sanitization" do
html = "<custom-allowed-element><p>text</p></custom-allowed-element>"
assert_equal "<p>text</p>", Govspeak::HtmlSanitizer.new(html).sanitize
assert_equal html, Govspeak::HtmlSanitizer.new(html).sanitize(allowed_elements: %w[custom-allowed-element])
end
end

0 comments on commit 496036c

Please sign in to comment.