Skip to content

Commit 5187a9e

Browse files
ooooooo-qtenderlove
authored andcommitted
fix XSS vulnerability when using translation
[CVE-2024-26143]
1 parent b4d3bfb commit 5187a9e

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

actionpack/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Fix possible XSS vulnerability with the `translate` method in controllers
2+
3+
CVE-2024-26143
4+
15
* Fix ReDoS in Accept header parsing
26

37
CVE-2024-26142

actionpack/lib/abstract_controller/translation.rb

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,25 @@ def translate(key, **options)
2121
key = "#{path}.#{action_name}#{key}"
2222
end
2323

24-
ActiveSupport::HtmlSafeTranslation.translate(key, **options)
24+
if options[:default]
25+
options[:default] = [options[:default]] unless options[:default].is_a?(Array)
26+
options[:default] = options[:default].map do |value|
27+
value.is_a?(String) ? ERB::Util.html_escape(value) : value
28+
end
29+
end
30+
31+
if options[:raise].nil?
32+
options[:default] = [] unless options[:default]
33+
options[:default] << MISSING_TRANSLATION
34+
end
35+
36+
result = ActiveSupport::HtmlSafeTranslation.translate(key, **options)
37+
38+
if result == MISSING_TRANSLATION
39+
+"translation missing: #{key}"
40+
else
41+
result
42+
end
2543
end
2644
alias :t :translate
2745

@@ -30,5 +48,9 @@ def localize(object, **options)
3048
I18n.localize(object, **options)
3149
end
3250
alias :l :localize
51+
52+
private
53+
MISSING_TRANSLATION = -(2**60)
54+
private_constant :MISSING_TRANSLATION
3355
end
3456
end

actionpack/test/abstract/translation_test.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,22 @@ def test_default_translation
8383
end
8484
end
8585

86+
def test_default_translation_as_safe_html
87+
@controller.stub :action_name, :index do
88+
translation = @controller.t(".twoz", default: ["<tag>"])
89+
assert_equal "&lt;tag&gt;", translation
90+
assert_equal true, translation.html_safe?
91+
end
92+
end
93+
94+
def test_default_translation_with_raise_as_safe_html
95+
@controller.stub :action_name, :index do
96+
translation = @controller.t(".twoz", raise: true, default: ["<tag>"])
97+
assert_equal "&lt;tag&gt;", translation
98+
assert_equal true, translation.html_safe?
99+
end
100+
end
101+
86102
def test_localize
87103
time, expected = Time.gm(2000), "Sat, 01 Jan 2000 00:00:00 +0000"
88104
I18n.stub :localize, expected do
@@ -126,6 +142,21 @@ def test_translate_escapes_interpolations_in_translations_with_a_html_suffix
126142
assert_equal true, translation.html_safe?
127143
end
128144
end
145+
146+
def test_translate_marks_translation_with_missing_html_key_as_safe_html
147+
@controller.stub :action_name, :index do
148+
translation = @controller.t("<tag>.html")
149+
assert_equal "translation missing: <tag>.html", translation
150+
assert_equal false, translation.html_safe?
151+
end
152+
end
153+
def test_translate_marks_translation_with_missing_nested_html_key_as_safe_html
154+
@controller.stub :action_name, :index do
155+
translation = @controller.t(".<tag>.html")
156+
assert_equal "translation missing: abstract_controller.testing.translation.index.<tag>.html", translation
157+
assert_equal false, translation.html_safe?
158+
end
159+
end
129160
end
130161
end
131162
end

0 commit comments

Comments
 (0)