Skip to content

Commit 857f2e4

Browse files
ooooooo-qtenderlove
authored andcommitted
fix XSS vulnerability when using translation
[CVE-2024-26143]
1 parent a3f3c3e commit 857f2e4

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

actionpack/lib/abstract_controller/translation.rb

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

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

@@ -32,5 +50,9 @@ def localize(object, **options)
3250
I18n.localize(object, **options)
3351
end
3452
alias :l :localize
53+
54+
private
55+
MISSING_TRANSLATION = -(2**60)
56+
private_constant :MISSING_TRANSLATION
3557
end
3658
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)