why aren't triggers used for securing databases from web-apps?
Inizia con un esempio molto forzato:
Se il codice della pagina ha qualcosa di simile
query = "SELECT * FROM some_table WHERE this_column='" + user_supplied_value + "';"
E un utente malintenzionato ha inserito questo valore:
user_supplied_value = "';DROP TABLE some_table;'SELECT DATE()"
La query inviata al database è
query = "SELECT * FROM some_table WHERE this_column=''; DROP TABLE some_table; 'SELECT DATE()';"
Una funzione trigger dovrebbe analizzare e rifiutare in modo sicuro questa stringa:
"';DROP TABLE some_table;'SELECT DATE()"
Ma. Solitamente un trigger è associato a un'operazione di inserimento, aggiornamento o eliminazione. Il precedente SQL contenente la stringa di attacco contiene tre query, nessuna delle quali esegue un inserimento, aggiornamento o eliminazione. Quindi il trigger non verrebbe mai attivato, la convalida non si sarebbe mai verificata e "some_table" sarebbe scomparso.
Ma diciamo che c'era un INSERT con un trigger che si attiva prima che venga eseguito il commit di INSERT. Spetta ora a te fare la convalida che gli sviluppatori del motore hanno già fatto per il codice del driver. C'è molto spazio per errori, pochissimi benefici, e davvero nessun punto dal momento che le query parametrizzate fanno tutto questo in modo automatico e molto più sicuro.
L'uso di query parametrizzate assicura che l'aspetto SQL sia simile a prima che venga inviato al motore del database:
query = "SELECT * FROM some_table WHERE this_column='\'\; DROP TABLE some_table\;\'SELECT DATE()';"
Utilizzi i trigger per l'autorizzazione, il controllo, il controllo della versione, l'applicazione dei vincoli di business, ma non per la convalida dell'input.
What does he mean triggers don't work on the queries
Dipende da cosa intende per "lavoro", ma generalmente è perché ciò che ho descritto sopra:
- Un trigger non agisce sulla query stessa. È licenziato una volta il
parser determina l'operazione che la query sta tentando di eseguire.
Quindi, indipendentemente da cosa fa il trigger, la query dannosa è nel
sistema e potrebbe potenzialmente essere eseguito.
- Nell'esempio sopra,
nessun grilletto potrebbe mai sparare. Quindi un trigger non "funziona" se lo sei
trattando le query "SELECT".
wouldn't that be much easier to make a trigger check for injection
rather than "parameterizing" every line of code in the web app?
No, è molto, molto più difficile.
Effettuando la convalida dopo che la query è stata inviata significa che il codice dannoso sarà inserito nel tuo motore di database. Le tue funzioni di validazione devono essere perfette. Ogni singola funzione nel database deve utilizzare tali funzioni di convalida prima di eseguire una query. Hai due livelli di perfezione da incontrare. Altrimenti, quel codice malevolo potrebbe essere eseguito.
I programmatori di app web dovrebbero anche tenere traccia di tutte le operazioni di concatenazione delle stringhe utilizzate per creare query e per stringhe più lunghe potrebbe diventare disordinato.
Le query parametrizzate, d'altro canto, assicurano che l'input sia sterilizzato prima di farlo arrivare al tuo motore di database. Quindi le tue funzioni personalizzate e qualsiasi funzione integrata saranno al sicuro dallo sfruttamento.
I mean there's never a time when one should not use cfquery param
tags, right?
Si potrebbe farla franca se la query in esecuzione non prende alcun input. In generale, però, se hai a che fare con gli input ovunque nell'applicazione, per coerenza tutte le chiamate al database devono utilizzare il meccanismo più sicuro disponibile, ovvero la funzione di parametrizzazione fornita dalla libreria driver o dal framework dell'applicazione.