Hello community, here is the log from the commit of package rubygem-rails-html-sanitizer for openSUSE:Factory checked in at 2016-03-01 09:42:57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-rails-html-sanitizer (Old) and /work/SRC/openSUSE:Factory/.rubygem-rails-html-sanitizer.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "rubygem-rails-html-sanitizer" Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-rails-html-sanitizer/rubygem-rails-html-sanitizer.changes 2015-03-18 13:05:01.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.rubygem-rails-html-sanitizer.new/rubygem-rails-html-sanitizer.changes 2016-03-01 09:43:06.000000000 +0100 @@ -1,0 +2,8 @@ +Tue Jan 26 05:35:48 UTC 2016 - coolo@suse.com + +- updated to version 1.0.3: + * boo#963326: CVE-2015-7578: XSS vulnerability via attributes + * boo#963327: CVE-2015-7579: XSS vulnerability + * boo#963328: CVE-2015-7580: XSS via whitelist sanitizer + +------------------------------------------------------------------- Old: ---- rails-html-sanitizer-1.0.2.gem New: ---- rails-html-sanitizer-1.0.3.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-rails-html-sanitizer.spec ++++++ --- /var/tmp/diff_new_pack.7mvsyA/_old 2016-03-01 09:43:08.000000000 +0100 +++ /var/tmp/diff_new_pack.7mvsyA/_new 2016-03-01 09:43:08.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package rubygem-rails-html-sanitizer # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -24,7 +24,7 @@ # Name: rubygem-rails-html-sanitizer -Version: 1.0.2 +Version: 1.0.3 Release: 0 %define mod_name rails-html-sanitizer %define mod_full_name %{mod_name}-%{version} @@ -37,7 +37,7 @@ BuildRequires: %{rubygem gem2rpm} BuildRequires: %{ruby} BuildRequires: ruby-macros >= 5 -Url: https://github.com/rafaelfranca/rails-html-sanitizer +Url: https://github.com/rails/rails-html-sanitizer Source: http://rubygems.org/gems/%{mod_full_name}.gem Source1: gem2rpm.yml Summary: HTML sanitization to Rails applications (part of Rails) @@ -53,7 +53,7 @@ %install %gem_install \ - --doc-files="CHANGELOG.md LICENSE.txt README.md" \ + --doc-files="CHANGELOG.md README.md" \ -f %gem_packages ++++++ rails-html-sanitizer-1.0.2.gem -> rails-html-sanitizer-1.0.3.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/LICENSE.txt new/LICENSE.txt --- old/LICENSE.txt 2015-03-10 21:28:27.000000000 +0100 +++ new/LICENSE.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,22 +0,0 @@ -Copyright (c) 2013 Rafael Mendonça França, Kasper Timm Hansen - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 2015-03-10 21:28:27.000000000 +0100 +++ new/README.md 2016-01-25 19:28:23.000000000 +0100 @@ -132,10 +132,11 @@ - [`Nokogiri::XML::Node`](http://nokogiri.org/Nokogiri/XML/Node.html) - [Nokogiri](http://nokogiri.org) -## Contributing +## Contributing to Rails Html Sanitizers -1. Fork it -2. Create your feature branch (`git checkout -b my-new-feature`) -3. Commit your changes (`git commit -am 'Add some feature'`) -4. Push to the branch (`git push origin my-new-feature`) -5. Create new Pull Request +Rails Html Sanitizers is work of many contributors. You're encouraged to submit pull requests, propose features and discuss issues. + +See [CONTRIBUTING](CONTRIBUTING.md). + +## License +Rails Html Sanitizers is released under the [MIT License](MIT-LICENSE). Files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rails/html/sanitizer/version.rb new/lib/rails/html/sanitizer/version.rb --- old/lib/rails/html/sanitizer/version.rb 2015-03-10 21:28:27.000000000 +0100 +++ new/lib/rails/html/sanitizer/version.rb 2016-01-25 19:28:23.000000000 +0100 @@ -1,7 +1,7 @@ module Rails module Html class Sanitizer - VERSION = "1.0.2" + VERSION = "1.0.3" end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rails/html/sanitizer.rb new/lib/rails/html/sanitizer.rb --- old/lib/rails/html/sanitizer.rb 2015-03-10 21:28:27.000000000 +0100 +++ new/lib/rails/html/sanitizer.rb 2016-01-25 19:28:23.000000000 +0100 @@ -13,6 +13,10 @@ node.xpath(*xpaths).remove node end + + def properly_encode(fragment, options) + fragment.xml? ? fragment.to_xml(options) : fragment.to_html(options) + end end # === Rails::Html::FullSanitizer @@ -26,9 +30,12 @@ return unless html return html if html.empty? - Loofah.fragment(html).tap do |fragment| - remove_xpaths(fragment, XPATHS_TO_REMOVE) - end.text(options) + loofah_fragment = Loofah.fragment(html) + + remove_xpaths(loofah_fragment, XPATHS_TO_REMOVE) + loofah_fragment.scrub!(TextOnlyScrubber.new) + + properly_encode(loofah_fragment, encoding: 'UTF-8') end end @@ -97,6 +104,10 @@ attr_accessor :allowed_tags attr_accessor :allowed_attributes end + self.allowed_tags = Set.new(%w(strong em b i p code pre tt samp kbd var sub + sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dl dt dd abbr + acronym a img blockquote del ins)) + self.allowed_attributes = Set.new(%w(href src width height alt cite datetime title class name xml:lang abbr)) def initialize @permit_scrubber = PermitScrubber.new @@ -136,10 +147,6 @@ def allowed_attributes(options) options[:attributes] || self.class.allowed_attributes end - - def properly_encode(fragment, options) - fragment.xml? ? fragment.to_xml(options) : fragment.to_html(options) - end end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rails/html/scrubbers.rb new/lib/rails/html/scrubbers.rb --- old/lib/rails/html/scrubbers.rb 2015-03-10 21:28:27.000000000 +0100 +++ new/lib/rails/html/scrubbers.rb 2016-01-25 19:28:23.000000000 +0100 @@ -60,6 +60,11 @@ end def scrub(node) + if node.cdata? + text = node.document.create_text_node node.text + node.replace text + return CONTINUE + end return CONTINUE if skip_node?(node) unless keep_node?(node) @@ -76,7 +81,7 @@ end def skip_node?(node) - node.text? || node.cdata? + node.text? end def scrub_attribute?(name) @@ -100,6 +105,7 @@ if @attributes node.attribute_nodes.each do |attr| attr.remove if scrub_attribute?(attr.name) + scrub_attribute(node, attr) end scrub_css_attribute(node) @@ -123,6 +129,30 @@ end var end + + def scrub_attribute(node, attr_node) + attr_name = if attr_node.namespace + "#{attr_node.namespace.prefix}:#{attr_node.node_name}" + else + attr_node.node_name + end + + if Loofah::HTML5::WhiteList::ATTR_VAL_IS_URI.include?(attr_name) + # this block lifted nearly verbatim from HTML5 sanitization + val_unescaped = CGI.unescapeHTML(attr_node.value).gsub(Loofah::HTML5::Scrub::CONTROL_CHARACTERS,'').downcase + if val_unescaped =~ /^[a-z0-9][-+.a-z0-9]*:/ && ! Loofah::HTML5::WhiteList::ALLOWED_PROTOCOLS.include?(val_unescaped.split(Loofah::HTML5::WhiteList::PROTOCOL_SEPARATOR)[0]) + attr_node.remove + end + end + if Loofah::HTML5::WhiteList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name) + attr_node.value = attr_node.value.gsub(/url\s*\(\s*[^#\s][^)]+?\)/m, ' ') if attr_node.value + end + if Loofah::HTML5::WhiteList::SVG_ALLOW_LOCAL_HREF.include?(node.name) && attr_name == 'xlink:href' && attr_node.value =~ /^\s*[^#\s].*/m + attr_node.remove + end + + node.remove_attribute(attr_node.name) if attr_name == 'src' && attr_node.value !~ /[^[:space:]]/ + end end # === Rails::Html::TargetScrubber @@ -137,11 +167,31 @@ # If set, attributes included will be removed. class TargetScrubber < PermitScrubber def allowed_node?(node) - !@tags.include?(node.name) + !super end def scrub_attribute?(name) - @attributes.include?(name) + !super + end + end + + # === Rails::Html::TextOnlyScrubber + # + # Rails::Html::TextOnlyScrubber allows you to permit text nodes. + # + # Unallowed elements will be stripped, i.e. element is removed but its subtree kept. + class TextOnlyScrubber < Loofah::Scrubber + def initialize + @direction = :bottom_up + end + + def scrub(node) + if node.text? + CONTINUE + else + node.before node.children + node.remove + end end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2015-03-10 21:28:27.000000000 +0100 +++ new/metadata 2016-01-25 19:28:23.000000000 +0100 @@ -1,7 +1,7 @@ --- !ruby/object:Gem::Specification name: rails-html-sanitizer version: !ruby/object:Gem::Version - version: 1.0.2 + version: 1.0.3 platform: ruby authors: - Rafael Mendonça França @@ -9,7 +9,7 @@ autorequire: bindir: bin cert_chain: [] -date: 2015-03-10 00:00:00.000000000 Z +date: 2016-01-25 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: loofah @@ -90,7 +90,6 @@ extra_rdoc_files: [] files: - CHANGELOG.md -- LICENSE.txt - README.md - lib/rails-html-sanitizer.rb - lib/rails/html/sanitizer.rb @@ -98,7 +97,7 @@ - lib/rails/html/scrubbers.rb - test/sanitizer_test.rb - test/scrubbers_test.rb -homepage: https://github.com/rafaelfranca/rails-html-sanitizer +homepage: https://github.com/rails/rails-html-sanitizer licenses: - MIT metadata: {} @@ -118,7 +117,7 @@ version: '0' requirements: [] rubyforge_project: -rubygems_version: 2.4.5 +rubygems_version: 2.5.1 signing_key: specification_version: 4 summary: This gem is responsible to sanitize HTML fragments in Rails applications. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/sanitizer_test.rb new/test/sanitizer_test.rb --- old/test/sanitizer_test.rb 2015-03-10 21:28:27.000000000 +0100 +++ new/test/sanitizer_test.rb 2016-01-25 19:28:23.000000000 +0100 @@ -11,6 +11,16 @@ end end + def test_sanitize_nested_script + sanitizer = Rails::Html::WhiteListSanitizer.new + assert_equal '<script>alert("XSS");</script>', sanitizer.sanitize('<script><script></script>alert("XSS");<script><</script>/</script><script>script></script>', tags: %w(em)) + end + + def test_sanitize_nested_script_in_style + sanitizer = Rails::Html::WhiteListSanitizer.new + assert_equal '<script>alert("XSS");</script>', sanitizer.sanitize('<style><script></style>alert("XSS");<style><</style>/</style><style>script></style>', tags: %w(em)) + end + class XpathRemovalTestSanitizer < Rails::Html::Sanitizer def sanitize(html, options = {}) fragment = Loofah.fragment(html) @@ -104,9 +114,12 @@ assert_equal "Frozen string with no tags", full_sanitize("Frozen string with no tags".freeze) end - def test_full_sanitize_allows_turning_off_encoding_special_chars + def test_full_sanitize_respect_html_escaping_of_the_given_string + assert_equal 'test\r\nstring', full_sanitize('test\r\nstring') assert_equal '&', full_sanitize('&') - assert_equal '&', full_sanitize('&', encode_special_chars: false) + assert_equal '&', full_sanitize('&') + assert_equal '&', full_sanitize('&') + assert_equal 'omg <script>BOM</script>', full_sanitize('omg <script>BOM</script>') end def test_strip_links_with_tags_in_tags @@ -152,7 +165,7 @@ end def test_sanitize_script - assert_sanitized "a b c