diff options
author | Timm <kaspth@gmail.com> | 2013-06-12 15:59:34 +0200 |
---|---|---|
committer | Timm <kaspth@gmail.com> | 2014-06-11 17:53:28 +0200 |
commit | c94e24fbe7bcdf605cafcfabdf97454d1e1e0685 (patch) | |
tree | c87092cfabcbb09f8351722b6127dc7d37c87a8f /actionview/lib/action_view/helpers/sanitize_helper | |
parent | 47baab0c415690aeb71ef3bc4831a462d8ead47b (diff) | |
download | rails-c94e24fbe7bcdf605cafcfabdf97454d1e1e0685.tar.gz rails-c94e24fbe7bcdf605cafcfabdf97454d1e1e0685.tar.bz2 rails-c94e24fbe7bcdf605cafcfabdf97454d1e1e0685.zip |
Added Loofah as a dependency in actionview.gemspec.
Implemented ActionView: FullSanitizer, LinkSanitizer and WhiteListSanitizer in sanitizers.rb.
Deprecated protocol_separator and bad_tags.
Added new tests in sanitizers_test.rb and reimplemented assert_dom_equal with Loofah.
Diffstat (limited to 'actionview/lib/action_view/helpers/sanitize_helper')
-rw-r--r-- | actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb b/actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb new file mode 100644 index 0000000000..74be525581 --- /dev/null +++ b/actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb @@ -0,0 +1,116 @@ +require 'active_support/core_ext/class/attribute' +require 'active_support/deprecation' +require 'loofah' + +module ActionView + + class FullSanitizer + def sanitize(html, options = {}) + Loofah.fragment(html).text + end + end + + class LinkSanitizer + def initialize + @link_scrubber = Loofah::Scrubber.new do |node| + next unless node.name == 'a' + node.before node.children + node.remove + end + end + + def sanitize(html, options = {}) + Loofah.scrub_fragment(html, @link_scrubber).to_s + end + end + + class WhiteListSanitizer + def sanitize(html, options = {}) + return nil unless html + validate_options(options) + + loofah_fragment = Loofah.fragment(html) + loofah_fragment.scrub!(:strip) + loofah_fragment.xpath("./form").each { |form| form.remove } + loofah_fragment.to_s + end + + def sanitize_css(style_string) + Loofah::HTML5::Scrub.scrub_css style_string + end + + def protocol_separator + ActiveSupport::Deprecation.warn('protocol_separator has been deprecated and has no effect.') + end + + def protocol_separator=(value) + ActiveSupport::Deprecation.warn('protocol_separator= has been deprecated and has no effect.') + end + + def bad_tags + ActiveSupport::Deprecation.warn('bad_tags has been deprecated and has no effect.') + end + + class << self + def protocol_separator + ActiveSupport::Deprecation.warn('protocol_separator has been deprecated and has no effect.') + end + + def protocol_separator=(value) + ActiveSupport::Deprecation.warn('protocol_separator= has been deprecated and has no effect.') + end + + def bad_tags + ActiveSupport::Deprecation.warn('The bad_tags class attribute has been deprecated and has no effect. You can still affect the tags being sanitized using 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) + + 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 + + protected + def validate_options(options) + if options[:tags] && !options[:tags].is_a?(Enumerable) + raise ArgumentError, "You should pass :tags as an Enumerable" + end + + if options[:attributes] && !options[:attributes].is_a?(Enumerable) + raise ArgumentError, "You should pass :attributes as an Enumerable" + end + end + + def contains_bad_protocols?(attr_name, value) + protocol_separator = ':' + self.uri_attributes.include?(attr_name) && + (value =~ /(^[^\/:]*):|(�*58)|(p)|(�*3a)|(%|%)3A/i && !self.allowed_protocols.include?(value.split(protocol_separator).first.downcase.strip)) + end + end +end |