2010-06-09 8 views
30

Devo disinfettare una parte della query sql. Posso fare qualcosa di simile:Come disinfettare il frammento SQL in Rails

class << ActiveRecord::Base 
    public :sanitize_sql 
end 

str = ActiveRecord::Base.sanitize_sql(["AND column1 = ?", "two's"], '') 

Ma non è sicuro perché espongo metodo protetto. Qual è un modo migliore per farlo?

+3

Puoi darci un po 'più di contesto? 'sanitize_sql' e gli amici sono spesso chiamati all'interno delle classi derivate da AR :: Base, senza bisogno di modificare la visibilità – pilcrow

+0

Questo è un punto valido e valido. Mi limito ad usare i metodi privati ​​o protetti di qualcuno. – dimus

risposta

3

è possibile ignorare il protected ness del metodo invocando indirettamente:

str = ActiveRecord::Base.__send__(:sanitize_sql, ["AND column1 = ?", "two's"], '') 

... che sarà almeno pezzi di dover rifare quel metodo come public.

(io sono un po 'sospetto che in realtà bisogno di fare questo, ma quanto sopra funzionerà.)

+0

un uso è quello di disinfettare il comando sql da inviare a facebook api – lulalala

+17

non è un grande fan dell'utilizzo di send per aggirare la natura protetta dei metodi. – chug2k

13

ActiveRecord :: Base.connection.quote fa il trucco in Rails 3.x

41

si può semplicemente utilizzare:

ActiveRecord::Base::sanitize(string) 
+0

funziona per Rails 2.3.8 – MrYoshiji

+9

Questo delegato a 'ActiveRecord :: Base.connection.quote' (almeno in Rails 4) –

+1

Questo metodo è stato rimosso su [PR 26000] (https://github.com/rails/rails/pull/26000) – Scudelletti

4

Questa domanda non specifica che la risposta deve venire da ActiveRecord né specificare per quale versione di Rails dovrebbe essere. Per questo motivo (e perché è una delle prime e poche) risposte su come disinfettare i parametri in Rails ...


Ecco una soluzione che funziona con Rails 4:

In ActiveRecord::Sanitization::ClassMethods avete sanitize_sql_for_conditions e dei suoi due altri alias: sanitize_conditions e sanitize_sql. I tre fanno letteralmente la stessa identica cosa.

sanitize_sql_for_conditions

accetta un array, hash, o una stringa di condizioni SQL e disinfetta loro in un frammento SQL valido per una clausola WHERE.

Anche in ActiveRecord è necessario

sanitize_sql_for_assignment che

accetta un array, hash, o una stringa di condizioni SQL e disinfetta le in un frammento SQL valida una clausola SET.

  • metodi di cui sopra sono compresi nel ActiveRecord :: Base per impostazione predefinita e pertanto, sono inclusi in qualsiasi modello di ActiveRecord.

Inoltre, tuttavia, in ActionController avete ActionController::Parameters che consente di

scegliere quali attributi dovrebbero essere inseriti nella whitelist per l'aggiornamento di massa e quindi prevenire accidentalmente esporre ciò che non dovrebbe essere esposto . Fornisce due metodi per questo scopo: richiedono e permesso.

params = ActionController::Parameters.new(user: { name: 'Bryan', age: 21 }) 
req  = params.require(:user) # will throw exception if user not present 
opt  = params.permit(:name)  # name parameter is optional, returns nil if not present 
user = params.require(:user).permit(:name, :age) # user hash is required while `name` and `age` keys are optional 

Il "Parametri magico" si chiama Parametri Strong (docs here) ed è possibile utilizzare che per disinfettare i parametri in un controllore prima di inviarlo a un modello.

  • I metodi di cui sopra sono incluse per default in ActionController::Base e quindi sono inclusi in qualsiasi controller Rails.

Spero che questo aiuti chiunque, se non altro per imparare e demistificare Rails! :)

+0

Il comando 'require' e' consente' di sanitare i parametri contro l'iniezione SQL, o semplicemente di convalidare la loro presenza? – Matt

+2

Fa zero sanitizzazione, solo conferma la presenza – Jimmy

+2

@Matt: Jimmy è corretto, 'require' e' permit' non eseguono alcuna sanificazione da soli. Ma 'ActionController :: Parameters.new' fa il sanitizing, quindi tutti i controller dovrebbero già disinfettare tutti i parametri. Aggiornerò la mia risposta più tardi quando avrò tempo perché ho trovato anche questa gemma molto interessante chiamata rails-html-sanitizer https://github.com/rails/rails-html-sanitizer –

Problemi correlati