Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package rubygem-rails-html-sanitizer for 
openSUSE:Factory checked in at 2026-04-17 21:04:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-rails-html-sanitizer (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-rails-html-sanitizer.new.11940 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-rails-html-sanitizer"

Fri Apr 17 21:04:20 2026 rev:13 rq:1347656 version:1.7.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/rubygem-rails-html-sanitizer/rubygem-rails-html-sanitizer.changes
        2023-11-17 20:50:22.178965387 +0100
+++ 
/work/SRC/openSUSE:Factory/.rubygem-rails-html-sanitizer.new.11940/rubygem-rails-html-sanitizer.changes
     2026-04-17 21:04:52.579354487 +0200
@@ -1,0 +2,51 @@
+Fri Mar 13 08:43:49 UTC 2026 - Johannes Segitz <[email protected]>
+
+- Update to version 1.7.0
+  * Add Rails::HTML::Sanitizer.allowed_uri? which delegates to
+    Loofah::HTML5::Scrub.allowed_uri?, allowing the Rails framework to check
+    URI safety without a direct dependency on Loofah.
+  * The minimum Loofah dependency is now ~> 2.25.
+
+-------------------------------------------------------------------
+Mon Dec 16 14:03:38 UTC 2024 - Paolo Perego <[email protected]>
+
+- Update to version 1.6.2
+    * PermitScrubber fully supports frozen "allowed tags". 
+        - v1.6.1 introduced safety checks that may remove unsafe tags from the
+          allowed list, which introduced a regression for applications passing
+          a frozen array of allowed tags. Tags and attributes are now properly
+          copied when they are passed to the scrubber. 
+
+- Version 1.6.1 
+
+    * The dependency on Nokogiri is updated to v1.15.7 or >=1.16.8. This change
+      addresses CVE-2024-53985 (GHSA-w8gc-x259-rc7x).
+
+    * Disallowed tags will be pruned when they appear in foreign content (i.e.
+      SVG or MathML content), regardless of the prune: option value. 
Previously,
+      disallowed tags were "stripped" unless the gem was configured with the
+      prune: true option.
+
+      The CVEs addressed by this change are:
+        * CVE-2024-53986 (GHSA-638j-pmjw-jq48)
+        * CVE-2024-53987 (GHSA-2x5m-9ch4-qgrr)
+
+    * The tags "noscript", "mglyph", and "malignmark" will not be allowed, even
+      if explicitly added to the allowlist. If applications try to allow any of
+      these tags, a warning is emitted and the tags are removed from the
+      allow-list.
+
+      The CVEs addressed by this change are:
+        * CVE-2024-53988 (GHSA-cfjx-w229-hgx5)
+        * CVE-2024-53989 (GHSA-rxv5-gxqc-xx8g)
+
+      Please note that we may restore support for allowing "noscript" in a 
future
+      release. We do not expect to ever allow "mglyph" or "malignmark", though,
+      especially since browser support is minimal for these tags.
+
+    * Improve performance by eliminating needless operations on attributes that
+      are being removed.
+
+*Mike Dalessio*
+
+-------------------------------------------------------------------

Old:
----
  rails-html-sanitizer-1.6.0.gem

New:
----
  rails-html-sanitizer-1.7.0.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-rails-html-sanitizer.spec ++++++
--- /var/tmp/diff_new_pack.FLZQR1/_old  2026-04-17 21:04:53.239381670 +0200
+++ /var/tmp/diff_new_pack.FLZQR1/_new  2026-04-17 21:04:53.239381670 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package rubygem-rails-html-sanitizer
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # 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.6.0
+Version:        1.7.0
 Release:        0
 %define mod_name rails-html-sanitizer
 %define mod_full_name %{mod_name}-%{version}

++++++ rails-html-sanitizer-1.6.0.gem -> rails-html-sanitizer-1.7.0.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md
--- old/CHANGELOG.md    2023-05-26 15:20:35.000000000 +0200
+++ new/CHANGELOG.md    1980-01-02 01:00:00.000000000 +0100
@@ -1,3 +1,67 @@
+## v1.7.0 / 2026-02-24
+
+* Add `Rails::HTML::Sanitizer.allowed_uri?` which delegates to 
`Loofah::HTML5::Scrub.allowed_uri?`,
+  allowing the Rails framework to check URI safety without a direct dependency 
on Loofah.
+
+  The minimum Loofah dependency is now `~> 2.25`.
+
+  *Mike Dalessio*
+
+
+## v1.6.2 / 2024-12-12
+
+* `PermitScrubber` fully supports frozen "allowed tags".
+
+  v1.6.1 introduced safety checks that may remove unsafe tags from the allowed 
list, which
+  introduced a regression for applications passing a frozen array of allowed 
tags. Tags and
+  attributes are now properly copied when they are passed to the scrubber.
+
+  Fixes #195.
+
+  *Mike Dalessio*
+
+
+## 1.6.1 / 2024-12-02
+
+This is a performance and security release which addresses several possible 
XSS vulnerabilities.
+
+* The dependency on Nokogiri is updated to v1.15.7 or >=1.16.8.
+
+  This change addresses CVE-2024-53985 (GHSA-w8gc-x259-rc7x).
+
+  *Mike Dalessio*
+
+* Disallowed tags will be pruned when they appear in foreign content (i.e. SVG 
or MathML content),
+  regardless of the `prune:` option value. Previously, disallowed tags were 
"stripped" unless the
+  gem was configured with the `prune: true` option.
+
+  The CVEs addressed by this change are:
+
+  - CVE-2024-53986 (GHSA-638j-pmjw-jq48)
+  - CVE-2024-53987 (GHSA-2x5m-9ch4-qgrr)
+
+  *Mike Dalessio*
+
+* The tags "noscript", "mglyph", and "malignmark" will not be allowed, even if 
explicitly added to
+  the allowlist. If applications try to allow any of these tags, a warning is 
emitted and the tags
+  are removed from the allow-list.
+
+  The CVEs addressed by this change are:
+
+  - CVE-2024-53988 (GHSA-cfjx-w229-hgx5)
+  - CVE-2024-53989 (GHSA-rxv5-gxqc-xx8g)
+
+  Please note that we _may_ restore support for allowing "noscript" in a 
future release. We do not
+  expect to ever allow "mglyph" or "malignmark", though, especially since 
browser support is minimal
+  for these tags.
+
+  *Mike Dalessio*
+
+* Improve performance by eliminating needless operations on attributes that 
are being removed. #188
+
+  *Mike Dalessio*
+
+
 ## 1.6.0 / 2023-05-26
 
 * Dependencies have been updated:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       2023-05-26 15:20:35.000000000 +0200
+++ new/README.md       1980-01-02 01:00:00.000000000 +0100
@@ -30,10 +30,6 @@
 # => Bold no more!  See more here...
 ```
 
-HTML5 version:
-
-
-
 #### LinkSanitizer
 
 ```ruby
Binary 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     2023-05-26 15:20:35.000000000 
+0200
+++ new/lib/rails/html/sanitizer/version.rb     1980-01-02 01:00:00.000000000 
+0100
@@ -3,7 +3,7 @@
 module Rails
   module HTML
     class Sanitizer
-      VERSION = "1.6.0"
+      VERSION = "1.7.0"
     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     2023-05-26 15:20:35.000000000 +0200
+++ new/lib/rails/html/sanitizer.rb     1980-01-02 01:00:00.000000000 +0100
@@ -13,6 +13,10 @@
         def best_supported_vendor
           html5_support? ? Rails::HTML5::Sanitizer : Rails::HTML4::Sanitizer
         end
+
+        def allowed_uri?(uri_string)
+          Loofah::HTML5::Scrub.allowed_uri?(uri_string)
+        end
       end
 
       def sanitize(html, options = {})
@@ -106,6 +110,7 @@
                                            "ins",
                                            "kbd",
                                            "li",
+                                           "mark",
                                            "ol",
                                            "p",
                                            "pre",
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     2023-05-26 15:20:35.000000000 +0200
+++ new/lib/rails/html/scrubbers.rb     1980-01-02 01:00:00.000000000 +0100
@@ -56,11 +56,11 @@
       end
 
       def tags=(tags)
-        @tags = validate!(tags, :tags)
+        @tags = validate!(tags.dup, :tags)
       end
 
       def attributes=(attributes)
-        @attributes = validate!(attributes, :attributes)
+        @attributes = validate!(attributes.dup, :attributes)
       end
 
       def scrub(node)
@@ -72,10 +72,11 @@
         return CONTINUE if skip_node?(node)
 
         unless (node.element? || node.comment?) && keep_node?(node)
-          return STOP if scrub_node(node) == STOP
+          return STOP unless scrub_node(node) == CONTINUE
         end
 
         scrub_attributes(node)
+        CONTINUE
       end
 
       protected
@@ -100,15 +101,22 @@
         end
 
         def scrub_node(node)
-          node.before(node.children) unless prune # strip
+          # If a node has a namespace, then it's a tag in either a `math` or 
`svg` foreign context,
+          # and we should always prune it to avoid namespace confusion and 
mutation XSS vectors.
+          unless prune || node.namespace
+            node.before(node.children)
+          end
           node.remove
         end
 
         def scrub_attributes(node)
           if @attributes
             node.attribute_nodes.each do |attr|
-              attr.remove if scrub_attribute?(attr.name)
-              scrub_attribute(node, attr)
+              if scrub_attribute?(attr.name)
+                attr.remove
+              else
+                scrub_attribute(node, attr)
+              end
             end
 
             scrub_css_attribute(node)
@@ -130,6 +138,24 @@
           if var && !var.is_a?(Enumerable)
             raise ArgumentError, "You should pass :#{name} as an Enumerable"
           end
+
+          if var && name == :tags
+            if var.include?("mglyph")
+              warn("WARNING: 'mglyph' tags cannot be allowed by the 
PermitScrubber and will be scrubbed")
+              var.delete("mglyph")
+            end
+
+            if var.include?("malignmark")
+              warn("WARNING: 'malignmark' tags cannot be allowed by the 
PermitScrubber and will be scrubbed")
+              var.delete("malignmark")
+            end
+
+            if var.include?("noscript")
+              warn("WARNING: 'noscript' tags cannot be allowed by the 
PermitScrubber and will be scrubbed")
+              var.delete("noscript")
+            end
+          end
+
           var
         end
 
@@ -140,9 +166,7 @@
             attr_node.node_name
           end
 
-          if Loofah::HTML5::SafeList::ATTR_VAL_IS_URI.include?(attr_name)
-            return if Loofah::HTML5::Scrub.scrub_uri_attribute(attr_node)
-          end
+          return if 
Loofah::HTML5::SafeList::ATTR_VAL_IS_URI.include?(attr_name) && 
Loofah::HTML5::Scrub.scrub_uri_attribute(attr_node)
 
           if 
Loofah::HTML5::SafeList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)
             
Loofah::HTML5::Scrub.scrub_attribute_that_allows_local_ref(attr_node)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2023-05-26 15:20:35.000000000 +0200
+++ new/metadata        1980-01-02 01:00:00.000000000 +0100
@@ -1,16 +1,15 @@
 --- !ruby/object:Gem::Specification
 name: rails-html-sanitizer
 version: !ruby/object:Gem::Version
-  version: 1.6.0
+  version: 1.7.0
 platform: ruby
 authors:
 - Rafael Mendonça França
 - Kasper Timm Hansen
 - Mike Dalessio
-autorequire: 
 bindir: bin
 cert_chain: []
-date: 2023-05-26 00:00:00.000000000 Z
+date: 1980-01-02 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: loofah
@@ -18,28 +17,82 @@
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '2.21'
+        version: '2.25'
   type: :runtime
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '2.21'
+        version: '2.25'
 - !ruby/object:Gem::Dependency
   name: nokogiri
   requirement: !ruby/object:Gem::Requirement
     requirements:
-    - - "~>"
+    - - ">="
+      - !ruby/object:Gem::Version
+        version: 1.15.7
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.0
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.0.rc1
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.1
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.2
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.3
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.4
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.5
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.6
+    - - "!="
       - !ruby/object:Gem::Version
-        version: '1.14'
+        version: 1.16.7
   type: :runtime
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
-    - - "~>"
+    - - ">="
+      - !ruby/object:Gem::Version
+        version: 1.15.7
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.0
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.0.rc1
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.1
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.2
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.3
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.4
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.5
+    - - "!="
+      - !ruby/object:Gem::Version
+        version: 1.16.6
+    - - "!="
       - !ruby/object:Gem::Version
-        version: '1.14'
+        version: 1.16.7
 description: HTML sanitization for Rails applications
 email:
 - [email protected]
@@ -59,15 +112,15 @@
 - test/rails_api_test.rb
 - test/sanitizer_test.rb
 - test/scrubbers_test.rb
+- test/test_helper.rb
 homepage: https://github.com/rails/rails-html-sanitizer
 licenses:
 - MIT
 metadata:
   bug_tracker_uri: https://github.com/rails/rails-html-sanitizer/issues
-  changelog_uri: 
https://github.com/rails/rails-html-sanitizer/blob/v1.6.0/CHANGELOG.md
-  documentation_uri: https://www.rubydoc.info/gems/rails-html-sanitizer/1.6.0
-  source_code_uri: https://github.com/rails/rails-html-sanitizer/tree/v1.6.0
-post_install_message: 
+  changelog_uri: 
https://github.com/rails/rails-html-sanitizer/blob/v1.7.0/CHANGELOG.md
+  documentation_uri: https://www.rubydoc.info/gems/rails-html-sanitizer/1.7.0
+  source_code_uri: https://github.com/rails/rails-html-sanitizer/tree/v1.7.0
 rdoc_options: []
 require_paths:
 - lib
@@ -82,11 +135,11 @@
     - !ruby/object:Gem::Version
       version: '0'
 requirements: []
-rubygems_version: 3.4.10
-signing_key: 
+rubygems_version: 4.0.3
 specification_version: 4
 summary: This gem is responsible to sanitize HTML fragments in Rails 
applications.
 test_files:
 - test/rails_api_test.rb
 - test/sanitizer_test.rb
 - test/scrubbers_test.rb
+- test/test_helper.rb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/rails_api_test.rb new/test/rails_api_test.rb
--- old/test/rails_api_test.rb  2023-05-26 15:20:35.000000000 +0200
+++ new/test/rails_api_test.rb  1980-01-02 01:00:00.000000000 +0100
@@ -1,7 +1,6 @@
 # frozen_string_literal: true
 
-require "minitest/autorun"
-require "rails-html-sanitizer"
+require_relative "test_helper"
 
 class RailsApiTest < Minitest::Test
   def test_html_module_name_alias
@@ -85,4 +84,18 @@
     skip("no HTML5 support on this platform") unless 
Rails::HTML::Sanitizer.html5_support?
     assert_equal(Rails::HTML5::SafeListSanitizer, 
Rails::HTML5::Sanitizer.white_list_sanitizer)
   end
+
+  def test_allowed_uri_returns_true_for_allowed_protocols
+    assert(Rails::HTML::Sanitizer.allowed_uri?("https://example.com";))
+    assert(Rails::HTML::Sanitizer.allowed_uri?("http://example.com";))
+    assert(Rails::HTML::Sanitizer.allowed_uri?("mailto:[email protected]";))
+  end
+
+  def test_allowed_uri_returns_false_for_disallowed_protocols
+    refute(Rails::HTML::Sanitizer.allowed_uri?("javascript:alert(1)"))
+  end
+
+  def test_allowed_uri_returns_true_for_relative_uris
+    assert(Rails::HTML::Sanitizer.allowed_uri?("/relative/path"))
+  end
 end
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  2023-05-26 15:20:35.000000000 +0200
+++ new/test/sanitizer_test.rb  1980-01-02 01:00:00.000000000 +0100
@@ -1,10 +1,6 @@
 # frozen_string_literal: true
 
-require "minitest/autorun"
-require "rails-html-sanitizer"
-
-puts "nokogiri version info: #{Nokogiri::VERSION_INFO}"
-puts "html5 support: #{Rails::HTML::Sanitizer.html5_support?}"
+require_relative "test_helper"
 
 #
 #  NOTE that many of these tests contain multiple acceptable results.
@@ -728,8 +724,6 @@
     end
 
     def test_uri_escaping_of_href_attr_in_a_tag_in_safe_list_sanitizer
-      skip if RUBY_VERSION < "2.3"
-
       html = %{<a href='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
 
       text = safe_list_sanitize(html)
@@ -747,8 +741,6 @@
     end
 
     def test_uri_escaping_of_src_attr_in_a_tag_in_safe_list_sanitizer
-      skip if RUBY_VERSION < "2.3"
-
       html = %{<a src='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
 
       text = safe_list_sanitize(html)
@@ -766,8 +758,6 @@
     end
 
     def test_uri_escaping_of_name_attr_in_a_tag_in_safe_list_sanitizer
-      skip if RUBY_VERSION < "2.3"
-
       html = %{<a name='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
 
       text = safe_list_sanitize(html)
@@ -785,8 +775,6 @@
     end
 
     def test_uri_escaping_of_name_action_in_a_tag_in_safe_list_sanitizer
-      skip if RUBY_VERSION < "2.3"
-
       html = %{<a action='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
 
       text = safe_list_sanitize(html, attributes: ["action"])
@@ -926,7 +914,7 @@
         # libxml2
         "<svg><style>&lt;script&gt;alert(1)&lt;/script&gt;</style></svg>",
         # libgumbo
-        "<svg><style>alert(1)</style></svg>"
+        "<svg><style></style></svg>",
       ]
 
       assert_includes(acceptable_results, actual)
@@ -984,6 +972,76 @@
       assert_includes(acceptable_results, actual)
     end
 
+    def test_combination_of_svg_and_style_with_escaped_img_payload
+      # https://hackerone.com/reports/2503220
+      input, tags = "<svg><style>&lt;img src onerror=alert(1)>", ["svg", 
"style"]
+      actual = safe_list_sanitize(input, tags: tags)
+      acceptable_results = [
+        # libxml2
+        "<svg><style>&amp;lt;img src onerror=alert(1)&gt;</style></svg>",
+        # libgumbo
+        "<svg><style>&lt;img src onerror=alert(1)&gt;</style></svg>",
+      ]
+
+      assert_includes(acceptable_results, actual)
+    end
+
+    def test_combination_of_math_and_style_with_escaped_img_payload
+      # https://hackerone.com/reports/2503220
+      input, tags = "<math><style>&lt;img src onerror=alert(1)>", ["math", 
"style"]
+      actual = safe_list_sanitize(input, tags: tags)
+      acceptable_results = [
+        # libxml2
+        "<math><style>&amp;lt;img src onerror=alert(1)&gt;</style></math>",
+        # libgumbo
+        "<math><style>&lt;img src onerror=alert(1)&gt;</style></math>",
+      ]
+
+      assert_includes(acceptable_results, actual)
+    end
+
+    def test_combination_of_style_and_disallowed_svg_with_script_payload
+      # https://hackerone.com/reports/2519936
+      input, tags = "<svg><style><style 
class='</style><script>alert(1)</script>'>", ["style"]
+      actual = safe_list_sanitize(input, tags: tags)
+      acceptable_results = [
+        # libxml2
+        "<style>&lt;style class='</style>alert(1)'&gt;",
+        # libgumbo
+        "",
+      ]
+
+      assert_includes(acceptable_results, actual)
+    end
+
+    def test_combination_of_style_and_disallowed_math_with_script_payload
+      # https://hackerone.com/reports/2519936
+      input, tags = "<math><style><style 
class='</style><script>alert(1)</script>'>", ["style"]
+      actual = safe_list_sanitize(input, tags: tags)
+      acceptable_results = [
+        # libxml2
+        "<style>&lt;style class='</style>alert(1)'&gt;",
+        # libgumbo
+        "",
+      ]
+
+      assert_includes(acceptable_results, actual)
+    end
+
+    def test_math_with_disallowed_mtext_and_img_payload
+      # https://hackerone.com/reports/2519941
+      input, tags = "<math><mtext><table><mglyph><style><img src=: 
onerror=alert(1)>", ["math", "style"]
+      actual = safe_list_sanitize(input, tags: tags)
+      acceptable_results = [
+        # libxml2
+        "<math><style>&lt;img src=: onerror=alert(1)&gt;</style></math>",
+        # libgumbo
+        "<math></math>",
+      ]
+
+      assert_includes(acceptable_results, actual)
+    end
+
     def test_should_sanitize_illegal_style_properties
       raw      = %(display:block; position:absolute; left:0; top:0; 
width:100%; height:100%; z-index:1; background-color:black; 
background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); 
background-x:center; background-y:center; background-repeat:repeat;)
       expected = 
%(display:block;width:100%;height:100%;background-color:black;background-x:center;background-y:center;)
@@ -1034,6 +1092,66 @@
       assert_equal "", sanitize_css(raw)
     end
 
+    def test_should_prune_mglyph
+      # https://hackerone.com/reports/2519936
+      input = "<math><mtext><table><mglyph><style><img src=: onerror=alert(1)>"
+      tags = %w(math mtext table mglyph style).freeze
+
+      actual = nil
+      assert_output(nil, /WARNING: 'mglyph' tags cannot be allowed by the 
PermitScrubber/) do
+        actual = safe_list_sanitize(input, tags: tags)
+      end
+
+      acceptable_results = [
+        # libxml2
+        "<math><mtext><table><style>&lt;img src=: 
onerror=alert(1)&gt;</style></table></mtext></math>",
+        # libgumbo
+        "<math><mtext><style><img src=: 
onerror=alert(1)></style><table></table></mtext></math>",
+      ]
+
+      assert_includes(acceptable_results, actual)
+    end
+
+    def test_should_prune_malignmark
+      # https://hackerone.com/reports/2519936
+      input = "<math><mtext><table><malignmark><style><img src=: 
onerror=alert(1)>"
+      tags = %w(math mtext table malignmark style).freeze
+
+      actual = nil
+      assert_output(nil, /WARNING: 'malignmark' tags cannot be allowed by the 
PermitScrubber/) do
+        actual = safe_list_sanitize(input, tags: tags)
+      end
+
+      acceptable_results = [
+        # libxml2
+        "<math><mtext><table><style>&lt;img src=: 
onerror=alert(1)&gt;</style></table></mtext></math>",
+        # libgumbo
+        "<math><mtext><style><img src=: 
onerror=alert(1)></style><table></table></mtext></math>",
+      ]
+
+      assert_includes(acceptable_results, actual)
+    end
+
+    def test_should_prune_noscript
+      # https://hackerone.com/reports/2509647
+      input = "<div><noscript><p 
id='</noscript><script>alert(1)</script>'></noscript>"
+      tags = ["p", "div", "noscript"].freeze
+
+      actual = nil
+      assert_output(nil, /WARNING: 'noscript' tags cannot be allowed by the 
PermitScrubber/) do
+        actual = safe_list_sanitize(input, tags: tags, attributes: %w(id))
+      end
+
+      acceptable_results = [
+        # libxml2
+        "<div><p 
id=\"&lt;/noscript&gt;&lt;script&gt;alert(1)&lt;/script&gt;\"></p></div>",
+        # libgumbo
+        "<div><p id=\"</noscript><script>alert(1)</script>\"></p></div>",
+      ]
+
+      assert_includes(acceptable_results, actual)
+    end
+
     protected
       def safe_list_sanitize(input, options = {})
         module_under_test::SafeListSanitizer.new.sanitize(input, options)
@@ -1083,5 +1201,84 @@
   class HTML5SafeListSanitizerTest < Minitest::Test
     @module_under_test = Rails::HTML5
     include SafeListSanitizerTest
+
+    def 
test_should_not_be_vulnerable_to_nokogiri_foreign_style_serialization_bug
+      # https://hackerone.com/reports/2503220
+      input = "<svg><style>&lt;img src onerror=alert(1)>"
+      result = Rails::HTML5::SafeListSanitizer.new.sanitize(input, tags: 
["svg", "style"])
+      browser = Nokogiri::HTML5::Document.parse(result)
+      xss = browser.at_xpath("//img/@onerror")
+
+      assert_nil(xss)
+    end
+
+    def test_should_not_be_vulnerable_to_ns_confusion_2519936
+      # https://hackerone.com/reports/2519936
+      input = "<math><style><style class='</style><script>alert(1)</script>'>"
+      result = Rails::HTML5::SafeListSanitizer.new.sanitize(input, tags: 
["style"])
+      browser = Nokogiri::HTML5::Document.parse(result)
+      xss = browser.at_xpath("//script")
+
+      assert_nil(xss)
+    end
+
+    def test_should_not_be_vulnerable_to_ns_confusion_2519941
+      # https://hackerone.com/reports/2519941
+      input = "<math><mtext><table><mglyph><style><img src=: onerror=alert(1)>"
+      result = Rails::HTML5::SafeListSanitizer.new.sanitize(input, tags: 
%w(math style))
+      browser = Nokogiri::HTML5::Document.parse(result)
+      xss = browser.at_xpath("//img/@onerror")
+
+      assert_nil(xss)
+    end
+
+    def test_should_not_be_vulnerable_to_mglyph_namespace_confusion
+      # https://hackerone.com/reports/2519936
+      input = "<math><mtext><table><mglyph><style><img src=: onerror=alert(1)>"
+      tags = %w(math mtext table mglyph style)
+
+      result = nil
+      assert_output(nil, /WARNING/) do
+        result = safe_list_sanitize(input, tags: tags)
+      end
+
+      browser = Nokogiri::HTML5::Document.parse(result)
+      xss = browser.at_xpath("//img/@onerror")
+
+      assert_nil(xss)
+    end
+
+    def test_should_not_be_vulnerable_to_malignmark_namespace_confusion
+      # https://hackerone.com/reports/2519936
+      input = "<math><mtext><table><malignmark><style><img src=: 
onerror=alert(1)>"
+      tags = %w(math mtext table malignmark style)
+
+      result = nil
+      assert_output(nil, /WARNING/) do
+        result = safe_list_sanitize(input, tags: tags)
+      end
+
+      browser = Nokogiri::HTML5::Document.parse(result)
+      xss = browser.at_xpath("//img/@onerror")
+
+      assert_nil(xss)
+    end
+
+    def test_should_not_be_vulnerable_to_noscript_attacks
+      # https://hackerone.com/reports/2509647
+      skip("browser assertion requires parse_noscript_content_as_text") unless 
Nokogiri::VERSION >= "1.17"
+
+      input = '<noscript><p 
id="</noscript><script>alert(1)</script>"></noscript>'
+
+      result = nil
+      assert_output(nil, /WARNING/) do
+        result = Rails::HTML5::SafeListSanitizer.new.sanitize(input, tags: 
%w(p div noscript), attributes: %w(id class style))
+      end
+
+      browser = Nokogiri::HTML5::Document.parse(result, 
parse_noscript_content_as_text: true)
+      xss = browser.at_xpath("//script")
+
+      assert_nil(xss)
+    end
   end if loofah_html5_support?
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/scrubbers_test.rb new/test/scrubbers_test.rb
--- old/test/scrubbers_test.rb  2023-05-26 15:20:35.000000000 +0200
+++ new/test/scrubbers_test.rb  1980-01-02 01:00:00.000000000 +0100
@@ -1,7 +1,6 @@
 # frozen_string_literal: true
 
-require "minitest/autorun"
-require "rails-html-sanitizer"
+require_relative "test_helper"
 
 class ScrubberTest < Minitest::Test
   protected
@@ -121,6 +120,30 @@
     assert_scrubbed html, '<tag></tag><tag cooler=""></tag>'
   end
 
+  def test_does_not_allow_safelisted_mglyph
+    # https://hackerone.com/reports/2519936
+    assert_output(nil, /WARNING: 'mglyph' tags cannot be allowed by the 
PermitScrubber/) do
+      @scrubber.tags = ["div", "mglyph", "span"]
+    end
+    assert_equal(["div", "span"], @scrubber.tags)
+  end
+
+  def test_does_not_allow_safelisted_malignmark
+    # https://hackerone.com/reports/2519936
+    assert_output(nil, /WARNING: 'malignmark' tags cannot be allowed by the 
PermitScrubber/) do
+      @scrubber.tags = ["div", "malignmark", "span"]
+    end
+    assert_equal(["div", "span"], @scrubber.tags)
+  end
+
+  def test_does_not_allow_safelisted_noscript
+    # https://hackerone.com/reports/2509647
+    assert_output(nil, /WARNING: 'noscript' tags cannot be allowed by the 
PermitScrubber/) do
+      @scrubber.tags = ["div", "noscript", "span"]
+    end
+    assert_equal(["div", "span"], @scrubber.tags)
+  end
+
   def test_leaves_text
     assert_scrubbed("some text")
   end
@@ -207,11 +230,65 @@
     end
   end
 
-  def setup
-    @scrubber = ScrubStopper.new
+  class ScrubContinuer < Rails::HTML::PermitScrubber
+    def scrub_node(node)
+      Loofah::Scrubber::CONTINUE
+    end
   end
 
   def test_returns_stop_from_scrub_if_scrub_node_does
+    @scrubber = ScrubStopper.new
     assert_scrub_stopped "<script>remove me</script>"
   end
+
+  def test_returns_continue_from_scrub_if_scrub_node_does
+    @scrubber = ScrubContinuer.new
+    assert_node_skipped "<script>keep me</script>"
+  end
+end
+
+class PermitScrubberMinimalOperationsTest < ScrubberTest
+  class TestPermitScrubber < Rails::HTML::PermitScrubber
+    def initialize
+      @scrub_attribute_args = []
+      @scrub_attributes_args = []
+
+      super
+
+      self.tags = ["div"]
+      self.attributes = ["class"]
+    end
+
+    def scrub_attributes(node)
+      @scrub_attributes_args << node.name
+
+      super
+    end
+
+    def scrub_attribute(node, attr)
+      @scrub_attribute_args << [node.name, attr.name]
+
+      super
+    end
+  end
+
+  def test_does_not_scrub_removed_attributes
+    @scrubber = TestPermitScrubber.new
+
+    input = "<div class='foo' href='bar'></div>"
+    frag = scrub_fragment(input)
+    assert_equal("<div class=\"foo\"></div>", frag)
+
+    assert_equal([["div", "class"]], 
@scrubber.instance_variable_get(:@scrub_attribute_args))
+  end
+
+  def test_does_not_scrub_attributes_of_a_removed_node
+    @scrubber = TestPermitScrubber.new
+
+    input = "<div class='foo' href='bar'><svg 
xlink:href='asdf'><set></set></svg></div>"
+    frag = scrub_fragment(input)
+    assert_equal("<div class=\"foo\"></div>", frag)
+
+    assert_equal(["div"], 
@scrubber.instance_variable_get(:@scrub_attributes_args))
+  end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/test/test_helper.rb new/test/test_helper.rb
--- old/test/test_helper.rb     1970-01-01 01:00:00.000000000 +0100
+++ new/test/test_helper.rb     1980-01-02 01:00:00.000000000 +0100
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require "minitest/autorun"
+require "rails-html-sanitizer"
+
+puts "nokogiri version info: #{Nokogiri::VERSION_INFO}"
+puts "html5 support: #{Rails::HTML::Sanitizer.html5_support?}"

Reply via email to