CVE-2011-4319
Description
Cross-site scripting (XSS) vulnerability in the i18n translations helper method in Ruby on Rails 3.0.x before 3.0.11 and 3.1.x before 3.1.2, and the rails_xss plugin in Ruby on Rails 2.3.x, allows remote attackers to inject arbitrary web script or HTML via vectors related to a translations string whose name ends with an "html" substring.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Cross-site scripting in Ruby on Rails (3.0.x < 3.0.11, 3.1.x < 3.1.2, and 2.3.x via rails_xss) due to improper HTML escaping of interpolated values in `translate` helper when translation name ends with "html".
Vulnerability
A cross-site scripting (XSS) vulnerability exists in the translate (aliased as t) helper method of Ruby on Rails 3.0.x before 3.0.11, 3.1.x before 3.1.2, and in the rails_xss plugin for the 2.3.x series [1][3][4]. When a translation string key ends with an "html" substring (e.g., foo_html), the helper marks the translation as HTML-safe. However, it failed to HTML-escape interpolated arguments before insertion, allowing a remote attacker to inject arbitrary web script or HTML via user-controlled values passed to the translate method [4].
Exploitation
An attacker must be able to supply input that is used as an interpolation argument to the translate (or t) helper call within a view template, where the translation key ends with _html [3][4]. No authentication is required if the application renders user input in such a translation call. The attacker provides a crafted string containing JavaScript or HTML as the interpolation value, e.g., ''. The translation method, prior to the fix, directly inserts this unescaped string into the HTML output [4].
Impact
Successful exploitation leads to stored or reflected cross-site scripting (XSS), depending on how the application stores or reflects the user input [1][3]. The attacker can execute arbitrary JavaScript in the context of the victim's browser session, potentially stealing session cookies, performing actions on behalf of the user, or defacing the page. The privilege level is that of the victim user; no server-side code execution is achieved.
Mitigation
The following versions contain the fix: Ruby on Rails 3.0.11, 3.1.2 (released November 18, 2011), and users of the 2.3.x series should upgrade to the rails_xss plugin version that includes the same fix [1][4]. For Rails 3.0.x and 3.1.x, upgrading to the patched minor release eliminates the vulnerability. No workaround is documented for older versions that cannot be upgraded. The vulnerability is not listed on the CISA Known Exploited Vulnerabilities (KEV) catalog.
AI Insight generated on May 23, 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 |
|---|---|---|
actionpackRubyGems | >= 3.0.0, < 3.0.11 | 3.0.11 |
actionpackRubyGems | >= 3.1.0, < 3.1.2 | 3.1.2 |
Affected products
59cpe:2.3:a:rubyonrails:rails:2.3.10:*:*:*:*:*:*:*+ 55 more
- cpe:2.3:a:rubyonrails:rails:2.3.10:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.11:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.12:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.2:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.3:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.4:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.9:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:beta:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:beta2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:beta3:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:beta4:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:rc:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.10:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.10:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.1:pre:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.2:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.2:pre:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.3:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.4:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.5:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.5:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.6:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.6:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.6:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.7:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.7:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.7:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.8:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.8:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.8:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.8:rc3:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.8:rc4:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:rc3:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:rc4:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:rc5:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:beta1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc3:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc4:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc5:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc6:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc7:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc8:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.1:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.1:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.1:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.1:rc3:*:*:*:*:*:*
- (no CPE)
cpe:2.3:a:rubyonrails:ruby_on_rails:3.0.4:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:rubyonrails:ruby_on_rails:3.0.4:*:*:*:*:*:*:*
- (no CPE)range: >=3.0.0 <3.0.11, >=3.1.0 <3.1.2
Patches
2ba2d85012088_html translation should escape interpolated arguments
3 files changed · +29 −4
actionpack/CHANGELOG+14 −0 modified@@ -1,5 +1,19 @@ *Rails 3.0.11 (unreleased)* +* Fix XSS security vulnerability in the `translate` helper method. When using interpolation + in combination with HTML-safe translations, the interpolated input would not get HTML + escaped. *GH 3664* + + Before: + + translate('foo_html', :something => '<script>') # => "...<script>..." + + After: + + translate('foo_html', :something => '<script>') # => "...<script>..." + + *Sergey Nartimov* + * Implement a workaround for a bug in ruby-1.9.3p0 where an error would be raised while attempting to convert a template from one encoding to another.
actionpack/lib/action_view/helpers/translation_helper.rb+9 −4 modified@@ -45,11 +45,16 @@ module TranslationHelper # you know what kind of output to expect when you call translate in a template. def translate(key, options = {}) options.merge!(:rescue_format => :html) unless options.key?(:rescue_format) - translation = I18n.translate(scope_key_by_partial(key), options) - if html_safe_translation_key?(key) && translation.respond_to?(:html_safe) - translation.html_safe + if html_safe_translation_key?(key) + html_safe_options = options.dup + options.except(*I18n::RESERVED_KEYS).each do |name, value| + html_safe_options[name] = ERB::Util.html_escape(value.to_s) + end + translation = I18n.translate(scope_key_by_partial(key), html_safe_options) + + translation.respond_to?(:html_safe) ? translation.html_safe : translation else - translation + I18n.translate(scope_key_by_partial(key), options) end end alias :t :translate
actionpack/test/template/translation_helper_test.rb+6 −0 modified@@ -17,6 +17,7 @@ def setup :hello => '<a>Hello World</a>', :html => '<a>Hello World</a>', :hello_html => '<a>Hello World</a>', + :interpolated_html => '<a>Hello %{word}</a>', :array_html => %w(foo bar), :array => %w(foo bar) } @@ -83,6 +84,11 @@ def test_translate_marks_translations_with_a_html_suffix_as_safe_html assert translate(:'translations.hello_html').html_safe? end + def test_translate_escapes_interpolations_in_translations_with_a_html_suffix + assert_equal '<a>Hello <World></a>', translate(:'translations.interpolated_html', :word => '<World>') + assert_equal '<a>Hello <World></a>', translate(:'translations.interpolated_html', :word => stub(:to_s => "<World>")) + end + def test_translation_returning_an_array_ignores_html_suffix assert_equal ["foo", "bar"], translate(:'translations.array_html') end
2d5b105d4bcb_html translation should escape interpolated arguments
3 files changed · +29 −4
actionpack/CHANGELOG.md+14 −0 modified@@ -1,5 +1,19 @@ ## Rails 3.1.2 (unreleased) ## +* Fix XSS security vulnerability in the `translate` helper method. When using interpolation + in combination with HTML-safe translations, the interpolated input would not get HTML + escaped. *GH 3664* + + Before: + + translate('foo_html', :something => '<script>') # => "...<script>..." + + After: + + translate('foo_html', :something => '<script>') # => "...<script>..." + + *Sergey Nartimov* + * Upgrade sprockets dependency to ~> 2.1.0 * Ensure that the format isn't applied twice to the cache key, else it becomes impossible
actionpack/lib/action_view/helpers/translation_helper.rb+9 −4 modified@@ -45,11 +45,16 @@ module TranslationHelper # you know what kind of output to expect when you call translate in a template. def translate(key, options = {}) options.merge!(:rescue_format => :html) unless options.key?(:rescue_format) - translation = I18n.translate(scope_key_by_partial(key), options) - if html_safe_translation_key?(key) && translation.respond_to?(:html_safe) - translation.html_safe + if html_safe_translation_key?(key) + html_safe_options = options.dup + options.except(*I18n::RESERVED_KEYS).each do |name, value| + html_safe_options[name] = ERB::Util.html_escape(value.to_s) + end + translation = I18n.translate(scope_key_by_partial(key), html_safe_options) + + translation.respond_to?(:html_safe) ? translation.html_safe : translation else - translation + I18n.translate(scope_key_by_partial(key), options) end end alias :t :translate
actionpack/test/template/translation_helper_test.rb+6 −0 modified@@ -17,6 +17,7 @@ def setup :hello => '<a>Hello World</a>', :html => '<a>Hello World</a>', :hello_html => '<a>Hello World</a>', + :interpolated_html => '<a>Hello %{word}</a>', :array_html => %w(foo bar), :array => %w(foo bar) } @@ -83,6 +84,11 @@ def test_translate_marks_translations_with_a_html_suffix_as_safe_html assert translate(:'translations.hello_html').html_safe? end + def test_translate_escapes_interpolations_in_translations_with_a_html_suffix + assert_equal '<a>Hello <World></a>', translate(:'translations.interpolated_html', :word => '<World>') + assert_equal '<a>Hello <World></a>', translate(:'translations.interpolated_html', :word => stub(:to_s => "<World>")) + end + def test_translation_returning_an_array_ignores_html_suffix assert_equal ["foo", "bar"], translate(:'translations.array_html') end
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
17- github.com/advisories/GHSA-xxr8-833v-c7wcghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2011-4319ghsaADVISORY
- groups.google.com/group/rubyonrails-security/browse_thread/thread/2b61d70fb73c7cc5nvdWEB
- groups.google.com/group/rubyonrails-security/msg/c65c24fbc4b6dd82nvdWEB
- openwall.com/lists/oss-security/2011/11/18/8nvdWEB
- weblog.rubyonrails.org/2011/11/18/rails-3-0-11-has-been-releasednvdWEB
- weblog.rubyonrails.org/2011/11/18/rails-3-1-2-has-been-releasednvdWEB
- exchange.xforce.ibmcloud.com/vulnerabilities/71364nvdWEB
- github.com/rails/rails/commit/2d5b105d4bcb652550dda8b5613376d1b8beb70cghsaWEB
- github.com/rails/rails/commit/ba2d85012088fd0db0fab98b2e512c77c83cbadeghsaWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/actionpack/CVE-2011-4319.ymlghsaWEB
- groups.google.com/forum/ghsaWEB
- web.archive.org/web/20200228155840/http://www.securityfocus.com/bid/50722ghsaWEB
- web.archive.org/web/20210307005941/http://www.securitytracker.com/idghsaWEB
- osvdb.org/77199nvd
- www.securityfocus.com/bid/50722nvd
- www.securitytracker.com/idnvd
News mentions
0No linked articles in our index yet.