Skip to content

Commit

Permalink
fix XSS vulnerability when using translation
Browse files Browse the repository at this point in the history
  • Loading branch information
ooooooo-q authored and tenderlove committed Feb 21, 2024
1 parent b4d3bfb commit 5187a9e
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
4 changes: 4 additions & 0 deletions actionpack/CHANGELOG.md
@@ -1,3 +1,7 @@
* Fix possible XSS vulnerability with the `translate` method in controllers

CVE-2024-26143

* Fix ReDoS in Accept header parsing

CVE-2024-26142
Expand Down
24 changes: 23 additions & 1 deletion actionpack/lib/abstract_controller/translation.rb
Expand Up @@ -21,7 +21,25 @@ def translate(key, **options)
key = "#{path}.#{action_name}#{key}"
end

ActiveSupport::HtmlSafeTranslation.translate(key, **options)
if options[:default]
options[:default] = [options[:default]] unless options[:default].is_a?(Array)
options[:default] = options[:default].map do |value|
value.is_a?(String) ? ERB::Util.html_escape(value) : value
end
end

if options[:raise].nil?
options[:default] = [] unless options[:default]
options[:default] << MISSING_TRANSLATION
end

result = ActiveSupport::HtmlSafeTranslation.translate(key, **options)

if result == MISSING_TRANSLATION
+"translation missing: #{key}"
else
result
end
end
alias :t :translate

Expand All @@ -30,5 +48,9 @@ def localize(object, **options)
I18n.localize(object, **options)
end
alias :l :localize

private
MISSING_TRANSLATION = -(2**60)
private_constant :MISSING_TRANSLATION
end
end
31 changes: 31 additions & 0 deletions actionpack/test/abstract/translation_test.rb
Expand Up @@ -83,6 +83,22 @@ def test_default_translation
end
end

def test_default_translation_as_safe_html
@controller.stub :action_name, :index do
translation = @controller.t(".twoz", default: ["<tag>"])
assert_equal "&lt;tag&gt;", translation
assert_equal true, translation.html_safe?
end
end

def test_default_translation_with_raise_as_safe_html
@controller.stub :action_name, :index do
translation = @controller.t(".twoz", raise: true, default: ["<tag>"])
assert_equal "&lt;tag&gt;", translation
assert_equal true, translation.html_safe?
end
end

def test_localize
time, expected = Time.gm(2000), "Sat, 01 Jan 2000 00:00:00 +0000"
I18n.stub :localize, expected do
Expand Down Expand Up @@ -126,6 +142,21 @@ def test_translate_escapes_interpolations_in_translations_with_a_html_suffix
assert_equal true, translation.html_safe?
end
end

def test_translate_marks_translation_with_missing_html_key_as_safe_html
@controller.stub :action_name, :index do
translation = @controller.t("<tag>.html")
assert_equal "translation missing: <tag>.html", translation
assert_equal false, translation.html_safe?
end
end
def test_translate_marks_translation_with_missing_nested_html_key_as_safe_html
@controller.stub :action_name, :index do
translation = @controller.t(".<tag>.html")
assert_equal "translation missing: abstract_controller.testing.translation.index.<tag>.html", translation
assert_equal false, translation.html_safe?
end
end
end
end
end

1 comment on commit 5187a9e

@jbirdjavi
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this get backported to 6.1?

Please sign in to comment.