From 08d0a11a3f62718d601d39e617c834759cf59bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 11 Feb 2014 23:36:10 -0200 Subject: Escape format, negative_format and units options of number helpers Previously the values of these options were trusted leading to potential XSS vulnerabilities. Fixes: CVE-2014-0081 --- actionview/lib/action_view/helpers/number_helper.rb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'actionview/lib/action_view') diff --git a/actionview/lib/action_view/helpers/number_helper.rb b/actionview/lib/action_view/helpers/number_helper.rb index ad825cd1f1..7157a95146 100644 --- a/actionview/lib/action_view/helpers/number_helper.rb +++ b/actionview/lib/action_view/helpers/number_helper.rb @@ -384,20 +384,29 @@ module ActionView def delegate_number_helper_method(method, number, options) return unless number - options = escape_unsafe_delimiters_and_separators(options.symbolize_keys) + options = escape_unsafe_options(options.symbolize_keys) wrap_with_output_safety_handling(number, options.delete(:raise)) { ActiveSupport::NumberHelper.public_send(method, number, options) } end - def escape_unsafe_delimiters_and_separators(options) - options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator] && !options[:separator].html_safe? - options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter] && !options[:delimiter].html_safe? - options[:unit] = ERB::Util.html_escape(options[:unit]) if options[:unit] && !options[:unit].html_safe? + def escape_unsafe_options(options) + options[:format] = ERB::Util.html_escape(options[:format]) if options[:format] + options[:negative_format] = ERB::Util.html_escape(options[:negative_format]) if options[:negative_format] + options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator] + options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter] + options[:unit] = ERB::Util.html_escape(options[:unit]) if options[:unit] && !options[:unit].html_safe? + options[:units] = escape_units(options[:units]) if options[:units] && Hash === options[:units] options end + def escape_units(units) + Hash[units.map do |k, v| + [k, ERB::Util.html_escape(v)] + end] + end + def wrap_with_output_safety_handling(number, raise_on_invalid, &block) valid_float = valid_float?(number) raise InvalidNumberError, number if raise_on_invalid && !valid_float -- cgit v1.2.3