[Fix #2579] Protect get_value against method name injection

This commit is contained in:
Frederic Merizen 2018-09-27 19:50:45 +02:00
parent 6fa0c8d2d6
commit 103f466cb8

View file

@ -1,4 +1,6 @@
class DossierFieldService class DossierFieldService
@@column_whitelist = {}
class << self class << self
def fields(procedure) def fields(procedure)
fields = [ fields = [
@ -44,6 +46,8 @@ class DossierFieldService
end end
def get_value(dossier, table, column) def get_value(dossier, table, column)
assert_valid_column(dossier.procedure, table, column)
case table case table
when 'self' when 'self'
dossier.send(column) dossier.send(column)
@ -60,6 +64,16 @@ class DossierFieldService
end end
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) def filtered_ids(dossiers, filters)
filters.map do |filter| filters.map do |filter|
table = filter['table'] table = filter['table']
@ -140,6 +154,17 @@ class DossierFieldService
private 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) def sanitized_column(field)
table = field['table'] table = field['table']
table = ActiveRecord::Base.connection.quote_column_name((table == 'self' ? 'dossier' : table).pluralize) table = ActiveRecord::Base.connection.quote_column_name((table == 'self' ? 'dossier' : table).pluralize)