XSS in Action View
Description
In Action View before versions 5.2.4.4 and 6.0.3.3 there is a potential Cross-Site Scripting (XSS) vulnerability in Action View's translation helpers. Views that allow the user to control the default (not found) value of the t and translate helpers could be susceptible to XSS attacks. When an HTML-unsafe string is passed as the default for a missing translation key named html or ending in _html, the default string is incorrectly marked as HTML-safe and not escaped. This is patched in versions 6.0.3.3 and 5.2.4.4. A workaround without upgrading is proposed in the source advisory.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
CVE-2020-15169 is a stored XSS vulnerability in Rails Action View translation helpers that marks user-controlled default strings as HTML-safe when the translation key ends in '_html'.
Vulnerability
Overview
CVE-2020-15169 is a Cross-Site Scripting (XSS) vulnerability in Action View, the view layer of Ruby on Rails [1]. The flaw resides in the t and translate helpers, specifically when a developer allows user input to control the default (fallback) value for a missing translation key [4]. When the missing key is named html or ends with _html, Action View incorrectly marks the user-supplied default string as HTML-safe and does not escape it [1][4]. This bypasses Rails' default auto-escaping and can lead to XSS [1].
Exploitation
Details
To exploit this vulnerability, the attacker must be able to control the default parameter of a t or translate call for a missing translation key that ends in _html [4]. For example, in code such as <%= t("welcome_html", default: untrusted_user_controlled_string) %>, the untrusted_user_controlled_string is marked as safe and rendered without sanitization [4]. The attack requires the user to be able to inject arbitrary HTML/JavaScript through that parameter, enabling XSS in the context of the victim's browser.
Impact
A successful XSS attack allows an attacker to execute arbitrary JavaScript in the victim's browser [1]. This can lead to session hijacking, credential theft, defacement, or other malicious actions within the web application. The vulnerability has a CVSS v3.1 base score of 6.1 (Medium), reflecting the requirement that the user must control the default parameter and the key must end in _html [1].
Mitigation
Rails has patched this vulnerability in versions 5.2.4.4 and 6.0.3.3 [1][4]. Users running older or unsupported versions should upgrade to a patched release. As a workaround, developers can manually escape the default string using the html_escape helper (aliased as h) before passing it to the translation helper [4]. For example: <%= t("welcome_html", default: h(untrusted_user_controlled_string)) %>.
AI Insight generated on May 21, 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 |
|---|---|---|
actionviewRubyGems | < 5.2.4.4 | 5.2.4.4 |
actionviewRubyGems | >= 6.0.0.0, < 6.0.3.3 | 6.0.3.3 |
Affected products
22- ghsa-coords21 versionspkg:gem/actionviewpkg:rpm/opensuse/rmt-server&distro=openSUSE%20Leap%2015.1pkg:rpm/opensuse/rmt-server&distro=openSUSE%20Leap%2015.2pkg:rpm/opensuse/rmt-server&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/rubygem-actionview-5_1&distro=openSUSE%20Leap%2015.4pkg:rpm/suse/rmt-server&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-ESPOSpkg:rpm/suse/rmt-server&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-LTSSpkg:rpm/suse/rmt-server&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Public%20Cloud%2015%20SP1pkg:rpm/suse/rmt-server&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Public%20Cloud%2015%20SP2pkg:rpm/suse/rmt-server&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Server%20Applications%2015%20SP1pkg:rpm/suse/rmt-server&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Server%20Applications%2015%20SP2pkg:rpm/suse/rmt-server&distro=SUSE%20Linux%20Enterprise%20Server%2015-LTSSpkg:rpm/suse/rmt-server&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015pkg:rpm/suse/rubygem-actionview-4_2&distro=SUSE%20OpenStack%20Cloud%206-LTSSpkg:rpm/suse/rubygem-actionview-4_2&distro=SUSE%20OpenStack%20Cloud%207pkg:rpm/suse/rubygem-actionview-4_2&distro=SUSE%20OpenStack%20Cloud%20Crowbar%208pkg:rpm/suse/rubygem-actionview-4_2&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/rubygem-actionview-5_1&distro=SUSE%20Linux%20Enterprise%20High%20Availability%20Extension%2015%20SP1pkg:rpm/suse/rubygem-actionview-5_1&distro=SUSE%20Linux%20Enterprise%20High%20Availability%20Extension%2015%20SP2pkg:rpm/suse/rubygem-actionview-5_1&distro=SUSE%20Linux%20Enterprise%20High%20Availability%20Extension%2015%20SP3pkg:rpm/suse/rubygem-actionview-5_1&distro=SUSE%20Linux%20Enterprise%20High%20Availability%20Extension%2015%20SP4
< 5.2.4.4+ 20 more
- (no CPE)range: < 5.2.4.4
- (no CPE)range: < 2.6.5-lp151.2.18.2
- (no CPE)range: < 2.6.5-lp152.2.3.1
- (no CPE)range: < 2.6.13-1.1
- (no CPE)range: < 5.1.4-150000.3.6.1
- (no CPE)range: < 2.6.5-3.34.1
- (no CPE)range: < 2.6.5-3.34.1
- (no CPE)range: < 2.6.5-3.18.1
- (no CPE)range: < 2.6.5-3.3.1
- (no CPE)range: < 2.6.5-3.18.1
- (no CPE)range: < 2.6.5-3.3.1
- (no CPE)range: < 2.6.5-3.34.1
- (no CPE)range: < 2.6.5-3.34.1
- (no CPE)range: < 4.2.9-9.12.1
- (no CPE)range: < 4.2.9-9.12.1
- (no CPE)range: < 4.2.9-9.12.1
- (no CPE)range: < 4.2.9-9.12.1
- (no CPE)range: < 5.1.4-150000.3.6.1
- (no CPE)range: < 5.1.4-150000.3.6.1
- (no CPE)range: < 5.1.4-150000.3.6.1
- (no CPE)range: < 5.1.4-150000.3.6.1
- rails/actionviewv5Range: < 5.2.4.4
Patches
1e663f084460eMerge pull request from GHSA-cfjv-5498-mph5
2 files changed · +15 −1
actionview/lib/action_view/helpers/translation_helper.rb+8 −1 modified@@ -96,9 +96,13 @@ def translate(key, **options) end end + html_safe_options[:default] = MISSING_TRANSLATION unless html_safe_options[:default].blank? + translation = I18n.translate(fully_resolved_key, **html_safe_options.merge(raise: i18n_raise)) - if translation.respond_to?(:map) + if translation.equal?(MISSING_TRANSLATION) + translated_text = options[:default].first + elsif translation.respond_to?(:map) translated_text = translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element } else translated_text = translation.respond_to?(:html_safe) ? translation.html_safe : translation @@ -150,6 +154,9 @@ def localize(object, **options) alias :l :localize private + MISSING_TRANSLATION = Object.new + private_constant :MISSING_TRANSLATION + def scope_key_by_partial(key) stringified_key = key.to_s if stringified_key.start_with?(".")
actionview/test/template/translation_helper_test.rb+7 −0 modified@@ -247,6 +247,13 @@ def test_translate_with_last_default_not_named_html assert_equal false, translation.html_safe? end + def test_translate_does_not_mark_unsourced_string_default_as_html_safe + untrusted_string = "<script>alert()</script>" + translation = translate(:"translations.missing", default: [:"translations.missing_html", untrusted_string]) + assert_equal untrusted_string, translation + assert_not_predicate translation, :html_safe? + end + def test_translate_with_string_default translation = translate(:'translations.missing', default: "A Generic String") assert_equal "A Generic String", translation
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- github.com/advisories/GHSA-cfjv-5498-mph5ghsaADVISORY
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/XJ7NUWXAEVRQCROIIBV4C6WXO6IR3KSB/mitrevendor-advisoryx_refsource_FEDORA
- nvd.nist.gov/vuln/detail/CVE-2020-15169ghsaADVISORY
- www.debian.org/security/2020/dsa-4766ghsavendor-advisoryx_refsource_DEBIANWEB
- github.com/rails/rails/commit/e663f084460ea56c55c3dc76f78c7caeddeeb02eghsaWEB
- github.com/rails/rails/security/advisories/GHSA-cfjv-5498-mph5ghsax_refsource_CONFIRMWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/actionview/CVE-2020-15169.ymlghsaWEB
- groups.google.com/g/rubyonrails-security/c/b-C9kSGXYrcghsaWEB
- lists.debian.org/debian-lts-announce/2020/10/msg00015.htmlghsamailing-listx_refsource_MLISTWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/XJ7NUWXAEVRQCROIIBV4C6WXO6IR3KSBghsaWEB
News mentions
0No linked articles in our index yet.