L'hashing potrebbe impedire l'iniezione SQL?

22

Per un capriccio di recente ho deciso di lanciare il primo sito web corretto che ho creato sul mio server web locale che utilizzo per lo sviluppo. Ho pensato che sarebbe stato un ottimo ambiente lanciare qualche SQL a iniezione perché so che ci sono dei difetti e il sito era pensato solo per il mio sviluppo personale.

Ad ogni modo, per arrivare al punto, dopo alcuni tentativi il più lontano che potevo ottenere era che la pagina restituisse un errore nella dichiarazione. Stavo cercando di entrare in un account di prova specifico che ho impostato, (se il risultato restituisce più di un account generato un errore, quindi non mi aspettavo di selezionare ogni nome utente dove 1 = 1 funzionasse), ma ogni volta che ho ottenuto un risposta come se avessi inserito una password normale, errata. Ho dato un'occhiata al codice PHP e ho scoperto che stavo tagliando la password prima della query, quindi l'attacco veniva sottoposto a hashing prima che potesse fare del male.

Essendo nuovo alla sicurezza Web nel suo insieme e avendo interesse per lo sviluppo web, mi chiedevo se ci sono delle vulnerabilità con questo metodo di Iniezione SQL prevenzione come mi aspetto di non aver pensato a qualcosa. Giusto per chiarire, questo non vuole essere un "look ragazzi ho trovato qualcosa di nuovo" visto che ci sono molte scintille più brillanti nella sicurezza delle informazioni di me, che probabilmente lo avrebbero già capito, ma mi piacerebbe sapere perché questo probabilmente non è adatto come meccanismo di sicurezza.

    
posta lewis 19.12.2016 - 16:41
fonte

5 risposte

37

Quindi, l'hashing della password dell'utente prima di inserirlo nella query è una funzione di sicurezza casuale per impedire l'iniezione SQL, ma non è possibile farlo necessariamente con tutti gli input dell'utente. Se sto cercando un cliente per nome e ho una query come

Select * from Customer Where Name like '%userInput%'

Se imposto userInput come versione hash di ciò che è stato digitato, non funzionerebbe correttamente anche se Nome era anche sottoposto a hashing nel database, funzionerebbe solo per query di ricerca esatte. Quindi, se avessi un cliente con nome "Sue" e ho digitato una ricerca per "sue", non funzionerebbe. Inoltre, non conoscerei il nome dei clienti a meno che non ci fosse una corrispondenza esatta nella mia ricerca, il che non è pratico.

Il modo in cui si desidera impedire l'SQL injection non è quello di rendere le query come sopra, si vorrà elaborare e parametrizzare gli input in una query, eliminando cose come = s e altri simboli che non hanno senso nel contesto dell'input. Una buona guida per prevenire l'iniezione SQL può essere trovata qui .

    
risposta data 19.12.2016 - 17:08
fonte
7

Fondamentalmente sì, se l'input hash (rappresentato in formato Hex o Base64) prima di passarlo a SQL, non può più essere un vettore di attacco SQLi efficace. Lo stesso vale se tu parseInt l'input. Quelli semplicemente non supportano i caratteri necessari per un SQLi utile. (Ovvero per uscire dalla stringa quotata)

Questa tecnica ha un'utilità limitata nella pratica. cioè non sarebbe compatibile con alcune delle famose funzionalità SQL come LIKE , < , > ,
o ricerche di uguaglianza indicizzate ( = e <> usando l'indice)

Come nota a margine, vorrei sottolineare che hash password dovrebbe essere effettivamente salato . Se tali criteri sono stati soddisfatti nel tuo esempio, penso che non includerai più un hash nella clausola WHERE SQL.

    
risposta data 19.12.2016 - 17:16
fonte
1

Quello che stai facendo (inavvertitamente) è parte di ciò che è noto come "sanitizzazione dell'input", che sono passi che ogni applicazione dovrebbe intraprendere per ridurre i difetti (e quindi le vulnerabilità).

Un'app dovrebbe innanzitutto garantire che l'input non possa traboccare dalla capacità dell'app di accettare i dati. Ciò potrebbe significare controllare a lungo l'input o altrimenti rifiutare i dati sovradimensionati.

Successivamente, l'app dovrebbe verificare l'input su una lista bianca, se possibile, per assicurarsi che nessun input indesiderato possa entrare nella logica. In alcuni casi ciò potrebbe significare che l'input contiene solo caratteri alfanumerici validi. Ma a volte una whitelist non ha senso per quel particolare campo di input, eppure lo sviluppatore deve ancora prevenire l'iniezione, quindi incorporano una lista nera. La lista nera convalida l'input non contiene simboli noti per rendere possibile l'iniezione. Lo svantaggio delle blacklist è che proteggono solo contro ciò che lo sviluppatore sa bloccare. Un esempio potrebbe essere una lista nera che arresta un segno di virgola per impedire l'iniezione SQL; ma lo sviluppatore potrebbe non riconoscere quando l'input passa attraverso l'URL codificato che un% 27 diventerà un segno di citazione.

Internamente, l'applicazione deve essere scritta in modo difensivo per proteggersi da varie forme di iniezione. L'utilizzo di SQL parametrizzato (invece di costruire una query SQL utilizzando la concatenazione) aiuta a prevenire l'SQL injection. Ma molti altri luoghi in cui le terre di input dell'utente possono essere vulnerabili a diversi tipi di iniezione. I percorsi della directory possono essere influenzati se un utente malintenzionato immette qualcosa come "..\..\..\..\..\..\windows\cmd.exe" Le query XPath possono essere iniettate per manomettere i dati non autorizzati. E JavaScript può passare attraverso il database per manomettere il browser della vittima. Altre forme di difesa includono non rivelando messaggi di errore diagnostici interni nell'output e la registrazione per assistere nell'individuazione di potenziali aggressori.

Ciò che la tua app ha fatto è passare prima l'input ad una routine hash, che ha il duplice effetto di disinfettare i dati e limitarne la lunghezza prima che arrivi al passaggio SQL. È importante ricordare che l'input della routine hash potrebbe essere ancora vulnerabile a un buffer overflow. Cosa succede quando un utente malintenzionato immette una password di "aaaa[...repeated 1000 times...]aaaa_Evil_Injection_Here" ? La tua app deve ancora gestirla.

    
risposta data 19.12.2016 - 17:19
fonte
1

Come molti altri studenti, confondi lo spazio di archiviazione e il trasporto . E per proteggere quest'ultimo, stai deliberatamente rovinando il primo.

Devi capire che SQL injection non è chiamato "Database injection" per un motivo. Non è necessario proteggere il database, la memoria. Tutto ciò che serve per proteggere è il trasporto: la query SQL. Mentre lo spazio di archiviazione dovrebbe essere in grado di memorizzare i dati così com'è , o non avrà alcun valore. Se hai ancora bisogno di una prova per tale affermazione,

  • potrebbero esserci clienti diversi, che non hanno idea della "protezione" prodotta in casa
  • non c'è solo un confronto rigoroso, e non solo un confronto: ci sono helluvalot di dichiarazioni in cui i tuoi dati potrebbero essere coinvolti: aritmetica, ricerca sottostringa, varie conversioni, manipolazioni di stringhe e calcoli di tutti i tipi
  • un database non viene solo utilizzato per archiviare i dati ma anche per manipolarli. Prova a ordinare i tuoi nomi utente con hash
  • dopo tutto, a volte è necessario stampare i dati da un database.

Quindi puoi dire che qualsiasi misura di protezione che modifica i dati memorizzati in qualche modo è semplicemente sbagliata. E la tua idea non è semplicemente ben pensata.

    
risposta data 20.12.2016 - 12:33
fonte
0

Hashing protegge l'iniezione SQL del campo della password in virtù del passaggio che codifica il suo output binario in una stringa.

Questa protezione è normalmente inutile, ma è sufficiente se le seguenti ipotesi sono vere:

  • La tua applicazione non gestisce le stringhe ovunque tranne nome utente e password.
  • Spoglia il nome utente di ' e \ caratteri.

Se uno di questi non è vero o potrebbe essere in futuro, l'hashing non è una difesa utile. Questo elimina il 99,9% delle applicazioni web.

    
risposta data 20.12.2016 - 03:26
fonte

Leggi altre domande sui tag