Possible XSS vulnerability with certain configurations of rails-html-sanitizer 1.6.0
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.
| Package | Affected versions | Patched versions |
|---|---|---|
rails-html-sanitizerRubyGems | >= 1.6.0, < 1.6.1 | 1.6.1 |
Affected products
4- Range: = 1.6.0
- ghsa-coords2 versionspkg:gem/rails-html-sanitizerpkg:rpm/opensuse/rubygem-rails-html-sanitizer&distro=openSUSE%20Tumbleweed
>= 1.6.0, < 1.6.1+ 1 more
- (no CPE)range: >= 1.6.0, < 1.6.1
- (no CPE)range: < 1.7.0-1.1
- rails/rails-html-sanitizerv5Range: >= 1.6.0, < 1.6.1
Patches
1a0a3e8b76b69fix: disallow 'mglyph' and 'malignmark' from safe lists
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><img src=: onerror=alert(1)></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><img src=: onerror=alert(1)></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- github.com/advisories/GHSA-cfjx-w229-hgx5ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-53988ghsaADVISORY
- github.com/rails/rails-html-sanitizer/commit/a0a3e8b76b696446ffc6bffcff3bc7b7c6393c72ghsax_refsource_MISCWEB
- github.com/rails/rails-html-sanitizer/security/advisories/GHSA-cfjx-w229-hgx5ghsax_refsource_CONFIRMWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/rails-html-sanitizer/CVE-2024-53988.ymlghsaWEB
News mentions
0No linked articles in our index yet.