2011-10-23 11 views
5

Ecco il codice:Mongoide: come impedire la creazione di campi non definiti mediante assegnazione di massa?

class M 
    include Mongoid::Document 
    field :name 
end 

params = { name: "foo", age: 20 } 
M.create(params) 
#=> #<M name: "My Name", age: 20> 

noti che age non è stato definito, ma è stato salvato.

Questo è problematico (potenzialmente una fonte di DoS), perché un utente malintenzionato può aggiungere eventuali parametri in POST e campi sconosciuti con una stringa di grandi dimensioni può entrare di nascosto. (Ad es name=foo&bogus=#{'x'*1000000})

Finora, non ho potuto trova tutto tranne attr_accessible, ma non è davvero eccezionale per Mongoid poiché devi mantenere gli stessi nomi di campo sia in field sia in attr_accessible in tutti i tempi, in tutti i modelli. Non ASCIUTTO.

Penso che l'API attr_accessible sia ottima per ActiveRecord, perché ci sono a. non si definiscono esplicitamente i campi nei modelli (DRY) e b. è garantito che non ci sono possibilità che un campo inesistente venga salvato in RDB. Ma per Mongoid, penso che ci dovrebbe essere una soluzione migliore di attr_accessible.

Si noti che c'è un'impostazione di configurazione globale allow_dynamic_fields ma non si tratta di assegnazione di massa, quindi è fuori dal campo di applicazione in questa discussione, tuttavia penso che dovrebbe essere effettivamente una macro per modello e dovrebbe anche occuparsi dell'assegnazione di massa.

Come ti stai occupando di questo problema?

+1

Hai trovato una soluzione per questo? Anch'io sto affrontando lo stesso problema. – Rohit

risposta

1

Uso sempre attr_accessible nei modelli. Raramente mi sono ritrovato a includere tutti i campi come accessibili. Di solito ci sono sempre alcuni campi che non dovrebbero essere accessibili per l'assegnazione di massa. Se spesso bisogno di includere tutti gli attributi e siete preoccupati per la duplicazione:

attr_accessible *fields.keys 
0

Quello che ho fatto per risolvere questo problema, è utilizzare un callback prima di salvare nel mio modello:

set_callback(:save, :before) do |doc| 
    (doc.attributes.keys - fields.keys).each { |f| doc.unset(f) } 
end 

Questo modo, anche se ci sono attributi extra vengono rimossi prima di essere salvati.

Problemi correlati