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" and "style" elements are both explicitly 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 has a XSS flaw when HTML5 sanitization is enabled and both 'math' and 'style' tags are explicitly allowed; fixed in 1.6.1.
Vulnerability
Overview
CVE-2024-53986 is a cross-site scripting (XSS) vulnerability in the rails-html-sanitizer gem, version 1.6.0, when used with Rails >= 7.1.0. The issue arises when HTML5 sanitization is enabled and an application developer overrides the sanitizer's allowed tags to explicitly include both the math and style elements. Under these specific conditions, an attacker can inject malicious content that bypasses the sanitizer's filtering [2][4].
Exploitation
Conditions
Exploitation requires that the application uses HTML5 sanitization (e.g., via config.action_view.sanitizer_vendor = Rails::HTML5::Sanitizer) and that the allowed tags list includes both math and style. This can happen through application configuration, the sanitize helper's :tags option, or by setting Rails::HTML5::SafeListSanitizer.allowed_tags [4]. The vulnerability is rooted in a namespace confusion when disallowing certain elements like svg or math, as shown in the fix commit [3].
Impact
If exploited, an attacker can inject arbitrary HTML/JavaScript, leading to XSS attacks. This could allow session hijacking, defacement, or theft of sensitive information. The default configuration does not allow these tags, so only applications that have explicitly overridden the allowed tags are at risk [2][4].
Mitigation
The vulnerability is fixed in version 1.6.1 of rails-html-sanitizer. Users are strongly advised to upgrade immediately. No workaround is available other than removing math and style from the allowed tags list or disabling HTML5 sanitization [4].
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, < 1.6.1 (with Rails >= 7.1.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
1f02ffbb8465efix: Namespace confusion when disallowing 'svg' or 'math'
2 files changed · +68 −2
lib/rails/html/scrubbers.rb+5 −1 modified@@ -101,7 +101,11 @@ def keep_node?(node) 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
test/sanitizer_test.rb+63 −1 modified@@ -918,7 +918,7 @@ def test_combination_of_svg_and_style_with_script_payload # libxml2 "<svg><style><script>alert(1)</script></style></svg>", # libgumbo - "<svg><style>alert(1)</style></svg>" + "<svg><style></style></svg>", ] assert_includes(acceptable_results, actual) @@ -976,6 +976,48 @@ def test_combination_of_svg_and_style_with_img_payload_2 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><style class='</style>alert(1)'>", + # 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><style class='</style>alert(1)'>", + # 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><img src=: onerror=alert(1)></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;) @@ -1075,5 +1117,25 @@ class HTML4SafeListSanitizerTest < Minitest::Test class HTML5SafeListSanitizerTest < Minitest::Test @module_under_test = Rails::HTML5 include SafeListSanitizerTest + + 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 end if loofah_html5_support? 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-638j-pmjw-jq48ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-53986ghsaADVISORY
- github.com/rails/rails-html-sanitizer/commit/f02ffbb8465e73920b6de0da940f5530f855965eghsax_refsource_MISCWEB
- github.com/rails/rails-html-sanitizer/security/advisories/GHSA-638j-pmjw-jq48ghsax_refsource_CONFIRMWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/rails-html-sanitizer/CVE-2024-53986.ymlghsaWEB
News mentions
0No linked articles in our index yet.