Permalink
Browse files

_html translation should escape interpolated arguments

Conflicts:

	actionpack/CHANGELOG.md
  • Loading branch information...
1 parent a03f018 commit ba2d85012088fd0db0fab98b2e512c77c83cbade @lest lest committed with jonleighton Nov 17, 2011
View
@@ -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>') # => "...&lt;script&gt;..."
+
+ *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.
@@ -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
@@ -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 &lt;World&gt;</a>', translate(:'translations.interpolated_html', :word => '<World>')
+ assert_equal '<a>Hello &lt;World&gt;</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

0 comments on commit ba2d850

Please sign in to comment.