VYPR
Low severityNVD Advisory· Published Dec 2, 2024· Updated Dec 3, 2024

Possible XSS vulnerability with certain configurations of rails-html-sanitizer 1.6.0

CVE-2024-53988

Description

rails-html-sanitizer is responsible for sanitizing HTML fragments in Rails applications. There is a possible XSS vulnerability with certain configurations of Rails::HTML::Sanitizer 1.6.0 when used with Rails >= 7.1.0. A possible XSS vulnerability with certain configurations of Rails::HTML::Sanitizer may allow an attacker to inject content if HTML5 sanitization is enabled and the application developer has overridden the sanitizer's allowed tags where the "math", "mtext", "table", and "style" elements are allowed and either either "mglyph" or "malignmark" are allowed. This vulnerability is fixed in 1.6.1.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Rails HTML Sanitizer 1.6.0 with HTML5 sanitization has an XSS vulnerability when specific unsafe tags are allowed.

Vulnerability

Overview

CVE-2024-53988 is a cross-site scripting (XSS) vulnerability in the rails-html-sanitizer gem, version 1.6.0, affecting Rails applications using HTML5 sanitization (Rails >= 7.1.0) [1][2]. The root cause lies in an insufficiently restrictive safe list that permits the HTML5 MathML elements mglyph or malignmark when combined with the elements math, mtext, table, and style [3]. When an application overrides the sanitizer's allowed tags to include this specific combination, an attacker can inject arbitrary HTML or JavaScript that bypasses sanitization.

Exploitation

Conditions

Exploitation requires three preconditions: the application must use HTML5 sanitization (configurable via config.action_view.sanitizer_vendor), the developer must override the sanitizer's allowed tags (via config.action_view.sanitized_allowed_tags, sanitize helper :tags option, or Rails::HTML5::SafeListSanitizer.allowed_tags), and the override must include the exact set of problematic elements (math, mtext, table, style, and either mglyph or malignmark) [3][4]. The vulnerability does not affect default configurations, which disallow most of these tags except table [2][3]. An attacker could craft a malicious payload, such as ``, that would be passed unsanitized to the browser [4].

Impact

Successful exploitation allows an attacker to execute arbitrary JavaScript in the context of the victim's session, leading to potential data theft, session hijacking, or defacement [2][3]. The vulnerability is classified as a high-severity XSS issue because it can be triggered with a simple user-contributed HTML input, such as a comment body rendered via the sanitize helper [3].

Mitigation

The vulnerability is fixed in version 1.6.1 of the rails-html-sanitizer gem [1][2]. The fix explicitly disallows mglyph and malignmark from safe lists, preventing the dangerous combination [4]. Users should upgrade to 1.6.1 immediately. As a temporary workaround, developers can audit their allowed tags configuration to ensure they do not include the problematic combination [3]. No other versions of the gem (before 1.6.0) are affected [3].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
rails-html-sanitizerRubyGems
>= 1.6.0, < 1.6.11.6.1

Affected products

4

Patches

1
a0a3e8b76b69

fix: disallow 'mglyph' and 'malignmark' from safe lists

https://github.com/rails/rails-html-sanitizerMike DalessioDec 1, 2024via ghsa
3 files changed · +93 0
  • lib/rails/html/scrubbers.rb+13 0 modified
    @@ -134,6 +134,19 @@ def validate!(var, name)
               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
    +          end
    +
               var
             end
     
    
  • test/sanitizer_test.rb+72 0 modified
    @@ -1026,6 +1026,46 @@ def test_should_sanitize_across_newlines
           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)
    +
    +      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)
    +
    +      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
    +
         protected
           def safe_list_sanitize(input, options = {})
             module_under_test::SafeListSanitizer.new.sanitize(input, options)
    @@ -1075,5 +1115,37 @@ class HTML4SafeListSanitizerTest < Minitest::Test
       class HTML5SafeListSanitizerTest < Minitest::Test
         @module_under_test = Rails::HTML5
         include SafeListSanitizerTest
    +
    +    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
       end if loofah_html5_support?
     end
    
  • test/scrubbers_test.rb+8 0 modified
    @@ -121,6 +121,14 @@ def test_leaves_only_supplied_tags_and_attributes
         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_leaves_text
         assert_scrubbed("some text")
       end
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.