diff options
Diffstat (limited to 'lib/axlsx/workbook/worksheet/cell.rb')
| -rw-r--r-- | lib/axlsx/workbook/worksheet/cell.rb | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/lib/axlsx/workbook/worksheet/cell.rb b/lib/axlsx/workbook/worksheet/cell.rb index 364de1e9..5e2661c3 100644 --- a/lib/axlsx/workbook/worksheet/cell.rb +++ b/lib/axlsx/workbook/worksheet/cell.rb @@ -28,10 +28,9 @@ module Axlsx # @option options [String] color an 8 letter rgb specification # @option options [Number] formula_value The value to cache for a formula cell. # @option options [Symbol] scheme must be one of :none, major, :minor - # @option options [Boolean] escape_formulas - Whether to treat a value starting with an equal - # sign as formula (default) or as simple string. - # Allowing user generated data to be interpreted as formulas can be dangerous - # (see https://www.owasp.org/index.php/CSV_Injection for details). + # @option options [Boolean] escape_formulas Whether to treat values starting with an equals + # sign as formulas or as literal strings. Allowing user-generated data to be interpreted as + # formulas is a security risk. See https://www.owasp.org/index.php/CSV_Injection for details. def initialize(row, value = nil, options = {}) @row = row # Do not use instance vars if not needed to use less RAM @@ -40,15 +39,13 @@ module Axlsx type = options.delete(:type) || cell_type_from_value(value) self.type = type unless type == :string - escape_formulas = options[:escape_formulas] - self.escape_formulas = escape_formulas unless escape_formulas.nil? - val = options.delete(:style) self.style = val unless val.nil? || val == 0 val = options.delete(:formula_value) self.formula_value = val unless val.nil? parse_options(options) + self.escape_formulas = row.worksheet.escape_formulas if escape_formulas.nil? self.value = value value.cell = self if contains_rich_text? @@ -73,6 +70,10 @@ module Axlsx CELL_TYPES = [:date, :time, :float, :integer, :richtext, :string, :boolean, :iso_8601, :text].freeze + # Leading characters that indicate a formula. + # See: https://owasp.org/www-community/attacks/CSV_Injection + FORMULA_PREFIXES = ['-', '=', '+', '@', '%', '|', "\r", "\t"].freeze + # The index of the cellXfs item to be applied to this cell. # @return [Integer] # @see Axlsx::Styles @@ -132,16 +133,17 @@ module Axlsx self.value = @value unless !defined?(@value) || @value.nil? end - # Whether to treat a value starting with an equal - # sign as formula (default) or as simple string. - # Allowing user generated data to be interpreted as formulas can be dangerous - # (see https://www.owasp.org/index.php/CSV_Injection for details). + # Whether to treat values starting with an equals sign as formulas or as literal strings. + # Allowing user-generated data to be interpreted as formulas is a security risk. + # See https://www.owasp.org/index.php/CSV_Injection for details. # @return [Boolean] attr_reader :escape_formulas - def escape_formulas=(v) - Axlsx.validate_boolean(v) - @escape_formulas = v + # Sets whether to treat values starting with an equals sign as formulas or as literal strings. + # @param [Boolean] value The value to set. + def escape_formulas=(value) + Axlsx.validate_boolean(value) + @escape_formulas = value end # The value of this cell. @@ -170,7 +172,8 @@ module Axlsx !is_text_run? && # No inline styles [email protected]? && # Not nil [email protected]? && # Not empty - [email protected]_with?(?=) # Not a formula + !is_formula? && # Not a formula + !is_array_formula? # Not an array formula end # The inline font_name property for the cell @@ -384,10 +387,12 @@ module Axlsx def is_formula? return false if escape_formulas - type == :string && @value.to_s.start_with?(?=) + type == :string && @value.to_s.start_with?(*FORMULA_PREFIXES) end def is_array_formula? + return false if escape_formulas + type == :string && @value.to_s.start_with?('{=') && @value.to_s.end_with?('}') end |
