From 103f466cb8f60e6882d4ca7bd3e8ef194707cdd9 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Thu, 27 Sep 2018 19:50:45 +0200 Subject: [PATCH] [Fix #2579] Protect get_value against method name injection --- app/services/dossier_field_service.rb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/app/services/dossier_field_service.rb b/app/services/dossier_field_service.rb index bd6af85b9..8de8d50bd 100644 --- a/app/services/dossier_field_service.rb +++ b/app/services/dossier_field_service.rb @@ -1,4 +1,6 @@ class DossierFieldService + @@column_whitelist = {} + class << self def fields(procedure) fields = [ @@ -44,6 +46,8 @@ class DossierFieldService end def get_value(dossier, table, column) + assert_valid_column(dossier.procedure, table, column) + case table when 'self' dossier.send(column) @@ -60,6 +64,16 @@ class DossierFieldService end end + def assert_valid_column(procedure, table, column) + if !valid_column?(procedure, table, column) + raise "Invalid column #{table}.#{column}" + end + end + + def valid_column?(procedure, table, column) + valid_columns_for_table(procedure, table).include?(column) + end + def filtered_ids(dossiers, filters) filters.map do |filter| table = filter['table'] @@ -140,6 +154,17 @@ class DossierFieldService private + def valid_columns_for_table(procedure, table) + if !@@column_whitelist.key?(procedure.id) + @@column_whitelist[procedure.id] = fields(procedure) + .group_by { |field| field['table'] } + .map { |table, fields| [table, Set.new(fields.map { |field| field['column'] }) ] } + .to_h + end + + @@column_whitelist[procedure.id][table] || [] + end + def sanitized_column(field) table = field['table'] table = ActiveRecord::Base.connection.quote_column_name((table == 'self' ? 'dossier' : table).pluralize)