From 38620e1bedb2cd38188eb6d7090beab5107f7347 Mon Sep 17 00:00:00 2001 From: Timm Date: Sat, 12 Oct 2013 23:09:50 +0200 Subject: Completed integration of rails-html-sanitizer in SanitizeHelper. Deprecated protocol_separator accessors and bad_tags=. --- .../lib/action_view/helpers/sanitize_helper.rb | 37 +++--- .../helpers/sanitize_helper/sanitizers.rb | 137 -------------------- .../helpers/sanitize_helper/scrubbers.rb | 139 --------------------- 3 files changed, 19 insertions(+), 294 deletions(-) delete mode 100644 actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb delete mode 100644 actionview/lib/action_view/helpers/sanitize_helper/scrubbers.rb diff --git a/actionview/lib/action_view/helpers/sanitize_helper.rb b/actionview/lib/action_view/helpers/sanitize_helper.rb index 4d2c6e64d9..13f946efa0 100644 --- a/actionview/lib/action_view/helpers/sanitize_helper.rb +++ b/actionview/lib/action_view/helpers/sanitize_helper.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/object/try' -require 'action_view/helpers/sanitize_helper/sanitizers' +require 'active_support/deprecation' +require 'rails-html-sanitizer' module ActionView # = Action View Sanitize Helpers @@ -121,7 +122,7 @@ module ActionView attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer def sanitized_protocol_separator - white_list_sanitizer.protocol_separator + ActiveSupport::Deprecation.warn('protocol_separator has been deprecated and has no effect.') end def sanitized_uri_attributes @@ -129,7 +130,7 @@ module ActionView end def sanitized_bad_tags - white_list_sanitizer.bad_tags + ActiveSupport::Deprecation.warn('bad_tags has been deprecated and has no effect. You can still affect the tags being sanitized using Rails::Html::WhiteListSanitizer.bad_tags= which changes the allowed_tags.') end def sanitized_allowed_tags @@ -156,7 +157,7 @@ module ActionView white_list_sanitizer.allowed_protocols end - # Gets the ActionView::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 @@ -164,10 +165,10 @@ module ActionView # end # def full_sanitizer - @full_sanitizer ||= ActionView::FullSanitizer.new + @full_sanitizer ||= Rails::Html::FullSanitizer.new end - # Gets the ActionView::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 @@ -175,10 +176,10 @@ module ActionView # end # def link_sanitizer - @link_sanitizer ||= ActionView::LinkSanitizer.new + @link_sanitizer ||= Rails::Html::LinkSanitizer.new end - # Gets the ActionView::WhiteListSanitizer instance used by sanitize and +sanitize_css+. + # Gets the Rails::Html::WhiteListSanitizer instance used by sanitize and +sanitize_css+. # Replace with any object that responds to +sanitize+. # # class Application < Rails::Application @@ -186,12 +187,12 @@ module ActionView # end # def white_list_sanitizer - @white_list_sanitizer ||= ActionView::WhiteListSanitizer.new + @white_list_sanitizer ||= Rails::Html::WhiteListSanitizer.new end def sanitized_protocol_separator=(value) - ActionView::WhiteListSanitizer.protocol_separator = value + ActiveSupport::Deprecation.warn('protocol_separator= has been deprecated and has no effect.') end # Adds valid HTML attributes that the +sanitize+ helper checks for URIs. @@ -201,7 +202,7 @@ module ActionView # end # def sanitized_uri_attributes=(attributes) - ActionView::WhiteListSanitizer.update_uri_attributes(attributes) + Rails::Html::WhiteListSanitizer.update_uri_attributes(attributes) end # Adds to the Set of 'bad' tags for the +sanitize+ helper. @@ -211,7 +212,7 @@ module ActionView # end # def sanitized_bad_tags=(attributes) - ActionView::WhiteListSanitizer.bad_tags = attributes + Rails::Html::WhiteListSanitizer.bad_tags = attributes end # Adds to the Set of allowed tags for the +sanitize+ helper. @@ -221,7 +222,7 @@ module ActionView # end # def sanitized_allowed_tags=(attributes) - ActionView::WhiteListSanitizer.update_allowed_tags(attributes) + Rails::Html::WhiteListSanitizer.update_allowed_tags(attributes) end # Adds to the Set of allowed HTML attributes for the +sanitize+ helper. @@ -231,7 +232,7 @@ module ActionView # end # def sanitized_allowed_attributes=(attributes) - ActionView::WhiteListSanitizer.update_allowed_attributes(attributes) + Rails::Html::WhiteListSanitizer.update_allowed_attributes(attributes) end # Adds to the Set of allowed CSS properties for the #sanitize and +sanitize_css+ helpers. @@ -241,7 +242,7 @@ module ActionView # end # def sanitized_allowed_css_properties=(attributes) - ActionView::WhiteListSanitizer.update_allowed_css_properties(attributes) + Rails::Html::WhiteListSanitizer.update_allowed_css_properties(attributes) end # Adds to the Set of allowed CSS keywords for the +sanitize+ and +sanitize_css+ helpers. @@ -251,7 +252,7 @@ module ActionView # end # def sanitized_allowed_css_keywords=(attributes) - ActionView::WhiteListSanitizer.update_allowed_css_keywords(attributes) + Rails::Html::WhiteListSanitizer.update_allowed_css_keywords(attributes) end # Adds to the Set of allowed shorthand CSS properties for the +sanitize+ and +sanitize_css+ helpers. @@ -261,7 +262,7 @@ module ActionView # end # def sanitized_shorthand_css_properties=(attributes) - ActionView::WhiteListSanitizer.update_shorthand_css_properties(attributes) + Rails::Html::WhiteListSanitizer.update_shorthand_css_properties(attributes) end # Adds to the Set of allowed protocols for the +sanitize+ helper. @@ -271,7 +272,7 @@ module ActionView # end # def sanitized_allowed_protocols=(attributes) - ActionView::WhiteListSanitizer.update_allowed_protocols(attributes) + Rails::Html::WhiteListSanitizer.update_allowed_protocols(attributes) end end end diff --git a/actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb b/actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb deleted file mode 100644 index 7ff465ca52..0000000000 --- a/actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb +++ /dev/null @@ -1,137 +0,0 @@ -require 'active_support/core_ext/class/attribute' -require 'active_support/core_ext/object/blank' -require 'active_support/deprecation' - -require 'loofah' -require 'action_view/helpers/sanitize_helper/scrubbers' - -module ActionView - XPATHS_TO_REMOVE = %w{.//script .//form comment()} - - class Sanitizer # :nodoc: - def sanitize(html, options = {}) - raise NotImplementedError, "subclasses must implement" - end - - # call +remove_xpaths+ with string and get a string back - # call it with a node or nodeset and get back a node/nodeset - def remove_xpaths(html, xpaths) - if html.respond_to?(:xpath) - html.xpath(*xpaths).remove - html - else - remove_xpaths(Loofah.fragment(html), xpaths).to_s - end - end - end - - class FullSanitizer < Sanitizer - def sanitize(html, options = {}) - return unless html - return html if html.blank? - - Loofah.fragment(html).tap do |fragment| - remove_xpaths(fragment, XPATHS_TO_REMOVE) - end.text - end - end - - class LinkSanitizer < Sanitizer - def initialize - @link_scrubber = TargetScrubber.new - @link_scrubber.tags = %w(a href) - end - - def sanitize(html, options = {}) - Loofah.scrub_fragment(html, @link_scrubber).to_s - end - end - - class WhiteListSanitizer < Sanitizer - def initialize - @permit_scrubber = PermitScrubber.new - end - - def sanitize(html, options = {}) - return unless html - return html if html.blank? - - loofah_fragment = Loofah.fragment(html) - - if scrubber = options[:scrubber] - # No duck typing, Loofah ensures subclass of Loofah::Scrubber - loofah_fragment.scrub!(scrubber) - elsif options[:tags] || options[:attributes] - @permit_scrubber.tags = options[:tags] - @permit_scrubber.attributes = options[:attributes] - loofah_fragment.scrub!(@permit_scrubber) - else - remove_xpaths(loofah_fragment, XPATHS_TO_REMOVE) - loofah_fragment.scrub!(:strip) - end - - loofah_fragment.to_s - end - - def sanitize_css(style_string) - Loofah::HTML5::Scrub.scrub_css(style_string) - end - - def protocol_separator - self.class.protocol_separator - end - - def protocol_separator=(value) - self.class.protocol_separator - end - - def bad_tags - self.class.bad_tags - end - - class << self - def protocol_separator - ActiveSupport::Deprecation.warn('protocol_separator has been deprecated and has no effect.') - end - - def protocol_separator=(value) - protocol_separator - end - - def bad_tags - ActiveSupport::Deprecation.warn('bad_tags has been deprecated and has no effect. You can still affect the tags being sanitized using ActionView::WhiteListSanitizer.bad_tags= which changes the allowed_tags.') - end - - def bad_tags=(tags) - allowed_tags.replace(allowed_tags - tags) - end - end - - [:uri_attributes, :allowed_attributes, - :allowed_tags, :allowed_protocols, :allowed_css_properties, - :allowed_css_keywords, :shorthand_css_properties].each do |attr| - class_attribute attr, :instance_writer => false - - define_method "#{self}.update_#{attr}" do |arg| - attr.merge arg - end - end - - # Constants are from Loofahs source at lib/loofah/html5/whitelist.rb - self.uri_attributes = Loofah::HTML5::WhiteList::ATTR_VAL_IS_URI - - self.allowed_tags = Loofah::HTML5::WhiteList::ALLOWED_ELEMENTS - - self.bad_tags = Set.new %w(script form) - - self.allowed_attributes = Loofah::HTML5::WhiteList::ALLOWED_ATTRIBUTES - - self.allowed_css_properties = Loofah::HTML5::WhiteList::ALLOWED_CSS_PROPERTIES - - self.allowed_css_keywords = Loofah::HTML5::WhiteList::ALLOWED_CSS_KEYWORDS - - self.shorthand_css_properties = Loofah::HTML5::WhiteList::SHORTHAND_CSS_PROPERTIES - - self.allowed_protocols = Loofah::HTML5::WhiteList::ALLOWED_PROTOCOLS - end -end diff --git a/actionview/lib/action_view/helpers/sanitize_helper/scrubbers.rb b/actionview/lib/action_view/helpers/sanitize_helper/scrubbers.rb deleted file mode 100644 index 43826f5e60..0000000000 --- a/actionview/lib/action_view/helpers/sanitize_helper/scrubbers.rb +++ /dev/null @@ -1,139 +0,0 @@ -# === PermitScrubber -# -# PermitScrubber allows you to permit only your own tags and/or attributes. -# -# PermitScrubber can be subclassed to determine: -# - When a node should be skipped via +skip_node?+ -# - When a node is allowed via +allowed_node?+ -# - When an attribute should be scrubbed via +scrub_attribute?+ -# -# Subclasses don't need to worry if tags or attributes are set or not. -# If tags or attributes are not set, Loofah's behavior will be used. -# If you override +allowed_node?+ and no tags are set, it will not be called. -# Instead Loofahs behavior will be used. -# Likewise for +scrub_attribute?+ and attributes respectively. -# -# Text and CDATA nodes are skipped by default. -# Unallowed elements will be stripped, i.e. element is removed but its subtree kept. -# Supplied tags and attributes should be Enumerables -# -# +tags=+ -# If set, elements excluded will be stripped. -# If not, elements are stripped based on Loofahs +HTML5::Scrub.allowed_element?+ -# -# +attributes=+ -# If set, attributes excluded will be removed. -# If not, attributes are removed based on Loofahs +HTML5::Scrub.scrub_attributes+ -# -# class CommentScrubber < PermitScrubber -# def allowed_node?(node) -# %w(form script comment blockquote).exclude?(node.name) -# end -# -# def skip_node?(node) -# node.text? -# end -# -# def scrub_attribute?(name) -# name == "style" -# end -# end -# -# See the documentation for Nokogiri::XML::Node to understand what's possible -# with nodes: http://nokogiri.org/Nokogiri/XML/Node.html -class PermitScrubber < Loofah::Scrubber - attr_reader :tags, :attributes - - def initialize - @direction = :bottom_up - @tags, @attributes = nil, nil - end - - def tags=(tags) - @tags = validate!(tags, :tags) - end - - def attributes=(attributes) - @attributes = validate!(attributes, :attributes) - end - - def scrub(node) - return CONTINUE if skip_node?(node) - - unless keep_node?(node) - return STOP if scrub_node(node) == STOP - end - - scrub_attributes(node) - end - - protected - - def allowed_node?(node) - @tags.include?(node.name) - end - - def skip_node?(node) - node.text? || node.cdata? - end - - def scrub_attribute?(name) - @attributes.exclude?(name) - end - - def keep_node?(node) - if @tags - allowed_node?(node) - else - Loofah::HTML5::Scrub.allowed_element?(node.name) - end - end - - def scrub_node(node) - node.before(node.children) # strip - node.remove - end - - def scrub_attributes(node) - if @attributes - node.attributes.each do |name, _| - node.remove_attribute(name) if scrub_attribute?(name) - end - else - Loofah::HTML5::Scrub.scrub_attributes(node) - end - end - - def validate!(var, name) - if var && !var.is_a?(Enumerable) - raise ArgumentError, "You should pass :#{name} as an Enumerable" - end - var - end -end - -# === TargetScrubber -# -# Where PermitScrubber picks out tags and attributes to permit in -# sanitization, TargetScrubber targets them for removal -# -# The open architecture of PermitScrubber is used to redefine: -# - +allowed_node?+ -# # allowed if node is not in tags -# - +scrub_attribute?+ -# # should scrub if attribute name is not in attributes -# -# +tags=+ -# If set, elements included will be stripped. -# -# +attributes=+ -# If set, attributes included will be removed. -class TargetScrubber < PermitScrubber - def allowed_node?(node) - @tags.exclude?(node.name) - end - - def scrub_attribute?(name) - @attributes.include?(name) - end -end -- cgit v1.2.3