Domanda Posso proteggere da SQL Injection evadendo la citazione singola e l'input dell'utente circostante con virgolette singole?


Mi rendo conto che le interrogazioni SQL parametrizzate sono il modo ottimale per sanitare l'input dell'utente durante la creazione di query che contengono input dell'utente, ma mi chiedo cosa c'è di sbagliato nel prendere input dell'utente e sfuggire alle virgolette singole e circondare l'intera stringa con virgolette singole. Ecco il codice:

sSanitizedInput = "'" & Replace(sInput, "'", "''") & "'"

Ogni singola citazione che l'utente inserisce viene sostituita con doppie virgolette singole, che elimina la possibilità per gli utenti di terminare la stringa, quindi qualsiasi altra cosa che possono digitare, come il punto e virgola, i segni di percentuale, ecc., Faranno tutti parte della stringa e non effettivamente eseguito come parte del comando. Stiamo usando Microsoft SQL Server 2000, per cui credo che la citazione singola sia l'unico delimitatore di stringhe e l'unico modo per sfuggire al delimitatore di stringhe, quindi non c'è modo di eseguire qualsiasi cosa l'utente digiti.

Non vedo alcun modo per lanciare un attacco di SQL injection contro questo, ma mi rendo conto che se fosse così a prova di proiettile come mi sembra qualcuno lo avrebbe già pensato e sarebbe stata una pratica comune. La mia domanda è questa: cosa c'è di sbagliato in questo codice? Qualcuno conosce un modo per ottenere un attacco SQL injection oltre questa tecnica di sanitizzazione? Un esempio di input dell'utente che sfrutta questa tecnica sarebbe molto utile.

AGGIORNARE:

Grazie a tutti per le loro risposte; praticamente tutte le informazioni che ho trovato nella mia ricerca sono apparse su questa pagina da qualche parte, il che è un segno dell'intelligenza e dell'abilità delle persone che hanno dedicato del tempo fuori dai loro intensi giorni per aiutarmi con questa domanda.

La ragione per cui non ho ancora accettato nessuna delle risposte è che non conosco ancora alcun modo per avviare in modo efficace un attacco di SQL injection contro questo codice. Alcune persone hanno suggerito che una barra rovesciata sarebbe sfuggita a una virgoletta singola e avrebbe lasciato l'altra per terminare la stringa in modo che il resto della stringa venisse eseguita come parte del comando SQL e mi rendo conto che questo metodo avrebbe funzionato per iniettare SQL in un database mySQL, ma in MS SQL 2000 l'unico modo (che sono stato in grado di trovare) di uscire da una citazione singola è con un altro singolo-qoute; i backslash non lo faranno. E a meno che non ci sia un modo per fermare l'escape della citazione singola, nessuno del resto dell'input dell'utente verrà eseguito perché verrà preso come una stringa contigua.

Capisco che ci sono modi migliori per disinfettare l'input, ma sono molto più interessato a capire perché il metodo che ho fornito sopra non funzionerà. Se qualcuno sa di un modo specifico per montare un attacco di iniezione SQL contro questo metodo di sanificazione, mi piacerebbe vederlo.


124
2017-09-26 12:41


origine


risposte:


Prima di tutto, è solo una cattiva pratica. La convalida dell'input è sempre necessaria, ma è anche sempre incerta.
Peggio ancora, la convalida della blacklist è sempre problematica, è molto meglio definire in modo esplicito e rigoroso quali valori / formati accettate. Certo, questo non è sempre possibile - ma in una certa misura deve essere sempre fatto.
Alcuni documenti di ricerca sull'argomento:

Il punto è che qualsiasi lista nera che fai (e whitelist troppo permissive) può essere aggirata. L'ultimo collegamento al mio foglio mostra situazioni in cui è possibile aggirare anche l'escape delle virgolette.

Anche se queste situazioni non si applicano a te, è ancora una cattiva idea. Inoltre, a meno che la tua app non sia piccola, dovrai gestire la manutenzione e forse una certa dose di governance: come garantisci che venga eseguita correttamente, in ogni momento?

Il modo corretto per farlo:

  • Validazione whitelist: tipo, lunghezza, formato o valori accettati
  • Se vuoi inserire la lista nera, vai avanti. La fuga di quotazioni è buona, ma nel contesto delle altre attenuazioni.
  • Usa gli oggetti Command e Parameter, prepare e validare
  • Chiama solo le query parametrizzate.
  • Meglio ancora, utilizzare esclusivamente le stored procedure.
  • Evitare l'uso di SQL dinamico e non utilizzare la concatenazione di stringhe per creare query.
  • Se si utilizzano SP, è inoltre possibile limitare le autorizzazioni nel database solo all'esecuzione degli SP necessari e non accedere direttamente alle tabelle.
  • puoi anche verificare facilmente che l'intero codebase accede solo al DB tramite SPs ...

80
2017-09-26 14:18



Va bene, questa risposta riguarderà l'aggiornamento della domanda:

"Se qualcuno conosce un modo specifico per montare un attacco di iniezione SQL contro questo metodo di igienizzazione, mi piacerebbe vederlo."

Ora, oltre alla fuga di backslash di MySQL - e tenendo conto che stiamo parlando di MSSQL, ci sono in realtà 3 modi possibili di SQL ancora per iniettare il tuo codice

sSanitizedInput = "'" & Replace (sInput, "'", "''") & "'"

Tieni presente che questi non saranno tutti validi in ogni momento e dipendono molto dal tuo codice reale intorno ad esso:

  1. Iniezione SQL del secondo ordine: se una query SQL viene ricostruita in base ai dati recuperati dal database dopo essere scappato, i dati vengono concatenati senza caratteri di escape e possono essere iniettati in SQL indirettamente. Vedere
  2. Troncamento delle stringhe - (un po 'più complicato) - Scenario: hai due campi, ad esempio un nome utente e una password, e SQL li concatena entrambi. E entrambi i campi (o solo il primo) hanno un limite rigido alla lunghezza. Ad esempio, il nome utente è limitato a 20 caratteri. Di 'che hai questo codice:
username = left(Replace(sInput, "'", "''"), 20)

Poi quello che ottieni - è il nome utente, con caratteri di escape e poi ritagliato a 20 caratteri. Il problema qui - inserisco la mia citazione nel 20 ° carattere (ad esempio dopo 19 a), e la tua citazione di fuga sarà tagliata (nel 21 ° carattere). Quindi l'SQL

sSQL = "select * from USERS where username = '" + username + "'  and password = '" + password + "'"

combinato con il nome utente errato di cui sopra comporterà la password già in essere al di fuori le virgolette e conterrà direttamente il carico utile.
3. Il contrabbando Unicode - In alcune situazioni, è possibile passare un carattere unicode di alto livello che sembra come una citazione, ma non è - fino a quando non arriva al database, dove improvvisamente è. Dal momento che non è una citazione quando la si convalida, sarà facile ... Vedi la mia risposta precedente per maggiori dettagli e link alla ricerca originale.


37
2017-12-18 02:03



In poche parole: non eseguire mai query in fuga. Sei destinato a sbagliare qualcosa. Invece, usa query parametrizzate, o se non puoi farlo per qualche motivo, usa una libreria esistente che faccia questo per te. Non c'è motivo di farlo da solo.


26
2017-09-26 12:51



Mi rendo conto che è passato molto tempo dalla domanda, ma ..

Un modo per lanciare un attacco sulla procedura 'quote the argument' è con il troncamento delle stringhe. Secondo MSDN, in SQL Server 2000 SP4 (e SQL Server 2005 SP1), una stringa troppo lunga verrà troncata in modo silenzioso.

Quando si cita una stringa, la stringa aumenta di dimensioni. Ogni apostrofo viene ripetuto. Questo può quindi essere usato per spingere parti di SQL al di fuori del buffer. In questo modo è possibile tagliare in modo efficace le parti di una clausola where.

Questo probabilmente sarebbe utile soprattutto in uno scenario di pagina di 'utente admin' in cui si potrebbe abusare dell'istruzione 'update' per non eseguire tutti i controlli che avrebbe dovuto eseguire.

Quindi, se decidi di citare tutti gli argomenti, assicurati di sapere cosa succede con le dimensioni delle stringhe e fai in modo di non incappare in troncamenti.

Consiglierei di andare con i parametri. Sempre. Vorrei solo poterlo applicare nel database. E come effetto collaterale, è più probabile che si ottengano risultati migliori nella cache perché più dichiarazioni sembrano uguali. (Questo era certamente vero su Oracle 8)


17
2018-02-19 10:57



I servizi igienico-sanitari di input non sono qualcosa che vuoi fare a metà. Usa tutto il tuo culo. Usa le espressioni regolari sui campi di testo. Prova a trasferire i numeri al tipo numerico appropriato e segnala un errore di convalida se non funziona. È molto facile cercare i pattern di attacco nel tuo input, come '-. Supponiamo che tutti gli input dell'utente siano ostili.


8
2017-09-26 12:51



Ho usato questa tecnica quando si trattava della funzionalità di 'ricerca avanzata', dove la creazione di una query da zero era l'unica risposta valida. (Esempio: consentire all'utente di cercare prodotti basati su un insieme illimitato di vincoli sugli attributi del prodotto, visualizzando colonne e valori consentiti come controlli GUI per ridurre la soglia di apprendimento per gli utenti.)

Di per sé è sicuro AFAIK. Come indicato da un altro rispondente, tuttavia, potrebbe anche essere necessario gestire l'escape del backspace (anche se non quando si passa la query a SQL Server utilizzando ADO o ADO.NET, almeno - non può garantire per tutti i database o le tecnologie).

L'intoppo è che devi essere certo di quali stringhe contengono input dell'utente (sempre potenzialmente dannosi) e quali stringhe sono query SQL valide. Una delle trappole è se si utilizzano valori dal database: quei valori erano originariamente forniti dall'utente? Se è così, devono anche essere scappati. La mia risposta è cercare di disinfettare il più tardi possibile (ma non più tardi!), Quando costruisci la query SQL.

Tuttavia, nella maggior parte dei casi, il binding dei parametri è la strada da percorrere: è più semplice.


8
2017-09-26 12:51



In ogni caso, è una cattiva idea, come sembri saperlo.

Che dire di qualcosa come sfuggire alla citazione in una stringa come questa: \ '

La tua sostituzione comporterebbe: \ ''

Se il backslash esegue l'escape della prima citazione, la seconda citazione ha terminato la stringa.


6
2017-09-26 12:45



Risposta semplice: funzionerà a volte, ma non sempre. Si desidera utilizzare la convalida della white list su qualunque cosa lo fai, ma mi rendo conto che non è sempre possibile, quindi sei costretto ad andare con la lista nera delle ipotesi migliori. Allo stesso modo, si desidera utilizzare i processamenti parametrizzati memorizzati in qualunque cosa, ma ancora una volta, non è sempre possibile, quindi sei costretto a usare sp_execute con i parametri.

Ci sono modi per aggirare qualsiasi lista nera utilizzabile (e anche alcune whitelist).

Una buona recensione è qui: http://www.owasp.org/index.php/Top_10_2007-A2

Se hai bisogno di farlo come soluzione rapida per darti il ​​tempo di crearne uno reale, fallo. Ma non pensare di essere al sicuro.


5
2017-09-29 18:50