Skip to content

Commit

Permalink
Merge pull request #48293 from flavorjones/flavorjones-support-html5-…
Browse files Browse the repository at this point in the history
…sanitizer

Update Action View to use HTML5 standards-compliant sanitizers
  • Loading branch information
rafaelfranca committed May 30, 2023
2 parents ae02cd6 + ce43ac6 commit 54de0cb
Show file tree
Hide file tree
Showing 10 changed files with 467 additions and 54 deletions.
23 changes: 12 additions & 11 deletions Gemfile.lock
Expand Up @@ -52,7 +52,7 @@ PATH
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
rails-html-sanitizer (~> 1.6)
actiontext (7.1.0.alpha)
actionpack (= 7.1.0.alpha)
activerecord (= 7.1.0.alpha)
Expand All @@ -65,7 +65,7 @@ PATH
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
rails-html-sanitizer (~> 1.6)
activejob (7.1.0.alpha)
activesupport (= 7.1.0.alpha)
globalid (>= 0.3.6)
Expand Down Expand Up @@ -292,9 +292,9 @@ GEM
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
loofah (2.19.1)
loofah (2.21.3)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
nokogiri (>= 1.12.0)
mail (2.8.0.1)
mini_mime (>= 0.1.1)
net-imap
Expand All @@ -311,7 +311,7 @@ GEM
memoist (0.16.2)
mini_magick (4.12.0)
mini_mime (1.1.2)
mini_portile2 (2.8.1)
mini_portile2 (2.8.2)
minitest (5.17.0)
minitest-bisect (1.6.0)
minitest-server (~> 1.0)
Expand Down Expand Up @@ -346,12 +346,12 @@ GEM
net-smtp (0.3.3)
net-protocol
nio4r (2.5.8)
nokogiri (1.14.3)
mini_portile2 (~> 2.8.0)
nokogiri (1.15.2)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nokogiri (1.14.3-x86_64-darwin)
nokogiri (1.15.2-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.14.3-x86_64-linux)
nokogiri (1.15.2-x86_64-linux)
racc (~> 1.4)
os (1.1.4)
parallel (1.22.1)
Expand Down Expand Up @@ -388,8 +388,9 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.4.4)
loofah (~> 2.19, >= 2.19.1)
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
rainbow (3.1.1)
rake (13.0.6)
rb-fsevent (0.11.2)
Expand Down
2 changes: 1 addition & 1 deletion actionpack/actionpack.gemspec
Expand Up @@ -39,7 +39,7 @@ Gem::Specification.new do |s|
s.add_dependency "rack", ">= 2.2.4"
s.add_dependency "rack-session", ">= 1.0.1"
s.add_dependency "rack-test", ">= 0.6.3"
s.add_dependency "rails-html-sanitizer", "~> 1.0", ">= 1.2.0"
s.add_dependency "rails-html-sanitizer", "~> 1.6"
s.add_dependency "rails-dom-testing", "~> 2.0"
s.add_dependency "actionview", version

Expand Down
13 changes: 13 additions & 0 deletions actionview/CHANGELOG.md
@@ -1,3 +1,16 @@
* Add support for HTML5 standards-compliant sanitizers, and default to `Rails::HTML5::Sanitizer`
in the Rails 7.1 configuration if it is supported.

Action View's HTML sanitizers can be configured by setting
`config.action_view.sanitizer_vendor`. Supported values are `Rails::HTML4::Sanitizer` or
`Rails::HTML5::Sanitizer`.

The Rails 7.1 configuration will set this to `Rails::HTML5::Sanitizer` when it is supported, and
fall back to `Rails::HTML4::Sanitizer`. Previous configurations default to
`Rails::HTML4::Sanitizer`.

*Mike Dalessio*

* Add support for the HTML picture tag. It supports passing a String, an Array or a Block.
Supports passing properties directly to the img tag via the `:image` key.
Since the picture tag requires an img tag, the last element you provide will be used for the img tag.
Expand Down
2 changes: 1 addition & 1 deletion actionview/actionview.gemspec
Expand Up @@ -37,7 +37,7 @@ Gem::Specification.new do |s|

s.add_dependency "builder", "~> 3.1"
s.add_dependency "erubi", "~> 1.11"
s.add_dependency "rails-html-sanitizer", "~> 1.1", ">= 1.2.0"
s.add_dependency "rails-html-sanitizer", "~> 1.6"
s.add_dependency "rails-dom-testing", "~> 2.0"

s.add_development_dependency "actionpack", version
Expand Down
44 changes: 31 additions & 13 deletions actionview/lib/action_view/helpers/sanitize_helper.rb
Expand Up @@ -9,15 +9,17 @@ module Helpers # :nodoc:
# The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
# These helper methods extend Action View making them callable within your template files.
module SanitizeHelper
mattr_accessor :sanitizer_vendor, default: Rails::HTML4::Sanitizer

extend ActiveSupport::Concern

# Sanitizes HTML input, stripping all but known-safe tags and attributes.
#
# It also strips href/src attributes with unsafe protocols like
# <tt>javascript:</tt>, while also protecting against attempts to use Unicode,
# ASCII, and hex character references to work around these protocol filters.
# All special characters will be escaped.
# It also strips href/src attributes with unsafe protocols like <tt>javascript:</tt>, while
# also protecting against attempts to use Unicode, ASCII, and hex character references to work
# around these protocol filters.
#
# The default sanitizer is Rails::Html::SafeListSanitizer. See {Rails HTML
# The default sanitizer is Rails::HTML5::SafeListSanitizer. See {Rails HTML
# Sanitizers}[https://github.com/rails/rails-html-sanitizer] for more information.
#
# Custom sanitization rules can also be provided.
Expand All @@ -29,7 +31,7 @@ module SanitizeHelper
#
# * <tt>:tags</tt> - An array of allowed tags.
# * <tt>:attributes</tt> - An array of allowed attributes.
# * <tt>:scrubber</tt> - A {Rails::Html scrubber}[https://github.com/rails/rails-html-sanitizer]
# * <tt>:scrubber</tt> - A {Rails::HTML scrubber}[https://github.com/rails/rails-html-sanitizer]
# or {Loofah::Scrubber}[https://github.com/flavorjones/loofah] object that
# defines custom sanitization rules. A custom scrubber takes precedence over
# custom tags and attributes.
Expand All @@ -44,9 +46,9 @@ module SanitizeHelper
#
# <%= sanitize @comment.body, tags: %w(strong em a), attributes: %w(href) %>
#
# Providing a custom Rails::Html scrubber:
# Providing a custom Rails::HTML scrubber:
#
# class CommentScrubber < Rails::Html::PermitScrubber
# class CommentScrubber < Rails::HTML::PermitScrubber
# def initialize
# super
# self.tags = %w( form script comment blockquote )
Expand All @@ -61,7 +63,7 @@ module SanitizeHelper
# <%= sanitize @comment.body, scrubber: CommentScrubber.new %>
#
# See {Rails HTML Sanitizer}[https://github.com/rails/rails-html-sanitizer] for
# documentation about Rails::Html scrubbers.
# documentation about Rails::HTML scrubbers.
#
# Providing a custom Loofah::Scrubber:
#
Expand All @@ -79,6 +81,22 @@ module SanitizeHelper
# # In config/application.rb
# config.action_view.sanitized_allowed_tags = ['strong', 'em', 'a']
# config.action_view.sanitized_allowed_attributes = ['href', 'title']
#
# The default, starting in \Rails 7.1, is to use an HTML5 parser for sanitization (if it is
# available, see NOTE below). If you wish to revert back to the previous HTML4 behavior, you
# can do so by setting the following in your application configuration:
#
# # In config/application.rb
# config.action_view.sanitizer_vendor = Rails::HTML4::Sanitizer
#
# Or, if you're upgrading from a previous version of \Rails and wish to opt into the HTML5
# behavior:
#
# # In config/application.rb
# config.action_view.sanitizer_vendor = Rails::HTML5::Sanitizer
#
# NOTE: Rails::HTML5::Sanitizer is not supported on JRuby, so on JRuby platforms \Rails will
# fall back to use Rails::HTML4::Sanitizer.
def sanitize(html, options = {})
self.class.safe_list_sanitizer.sanitize(html, options)&.html_safe
end
Expand Down Expand Up @@ -126,7 +144,7 @@ module ClassMethods # :nodoc:
attr_writer :full_sanitizer, :link_sanitizer, :safe_list_sanitizer

def sanitizer_vendor
Rails::Html::Sanitizer
ActionView::Helpers::SanitizeHelper.sanitizer_vendor
end

def sanitized_allowed_tags
Expand All @@ -137,7 +155,7 @@ def sanitized_allowed_attributes
sanitizer_vendor.safe_list_sanitizer.allowed_attributes
end

# Gets the Rails::Html::FullSanitizer instance used by +strip_tags+. Replace with
# Gets the Rails::HTML::FullSanitizer instance used by +strip_tags+. Replace with
# any object that responds to +sanitize+.
#
# class Application < Rails::Application
Expand All @@ -147,7 +165,7 @@ def full_sanitizer
@full_sanitizer ||= sanitizer_vendor.full_sanitizer.new
end

# Gets the Rails::Html::LinkSanitizer instance used by +strip_links+.
# Gets the Rails::HTML::LinkSanitizer instance used by +strip_links+.
# Replace with any object that responds to +sanitize+.
#
# class Application < Rails::Application
Expand All @@ -157,7 +175,7 @@ def link_sanitizer
@link_sanitizer ||= sanitizer_vendor.link_sanitizer.new
end

# Gets the Rails::Html::SafeListSanitizer instance used by sanitize and +sanitize_css+.
# Gets the Rails::HTML::SafeListSanitizer instance used by sanitize and +sanitize_css+.
# Replace with any object that responds to +sanitize+.
#
# class Application < Rails::Application
Expand Down
6 changes: 6 additions & 0 deletions actionview/lib/action_view/railtie.rb
Expand Up @@ -46,6 +46,12 @@ class Railtie < Rails::Engine # :nodoc:
ActionView::Helpers::ContentExfiltrationPreventionHelper.prepend_content_exfiltration_prevention = prepend_content_exfiltration_prevention
end

initializer "action_view.sanitizer_vendor" do |app|
if klass = app.config.action_view.delete(:sanitizer_vendor)
ActionView::Helpers::SanitizeHelper.sanitizer_vendor = klass
end
end

config.after_initialize do |app|
button_to_generates_button_tag = app.config.action_view.delete(:button_to_generates_button_tag)
unless button_to_generates_button_tag.nil?
Expand Down

0 comments on commit 54de0cb

Please sign in to comment.