Esiste una lunghezza del campo troppo breve per consentire un'iniezione SQL dannosa?

51

Stavo leggendo di SQL injection e ho visto questo, che mi ha fatto riflettere:

input fields as small as possible to reduce the likelihood of a hacker being able to squeeze SQL code into the field without it being truncated (which usually leads to a T-SQL syntax error).

Fonte: Microsoft SQL Server 2008 R2 Unleashed

Qual è la dimensione del campo più breve in cui l'iniezione SQL può causare danni?

Con i danni apportati alla modifica del database o alla restituzione dei risultati non previsti dalla progettazione. Includere un marcatore di commento di fine ( -- ) in un campo di due caratteri non causerebbe alcun danno, ma causerebbe solo una query non riuscita. Il potenziale hacker potrebbe imparare che il campo è suscettibile all'iniezione, ma non è in grado di sfruttarlo.

    
posta James Jenkins 28.02.2017 - 17:18
fonte

8 risposte

85

No, non c'è lunghezza troppo breve per essere sfruttata (almeno in alcune situazioni).

Un filtro di lunghezza non è una protezione valida contro l'iniezione SQL e le istruzioni preparate sono l'unica difesa adeguata.

Un filtro di lunghezza è comunque una buona misura come difesa in profondità (come i filtri interi, i filtri alfanumerici, ecc.). Esistono molte situazioni in cui ad es. l'input valido non può mai essere superiore a 30 caratteri, ma laddove uno sfruttamento significativo richiede di più. Dovrebbe (ma probabilmente non lo è) senza dire che qualsiasi filtraggio come difesa in profondità deve avvenire sul lato server in quanto qualsiasi cosa sul lato client può essere semplicemente aggirata.

Bypass di restrizione

Le clausole di restrizione (ad esempio AND / OR ) possono essere ignorate da due caratteri, che possono causare un danno reale, non solo una query non riuscita. L'esempio più semplice è un accesso (altri esempi potrebbero essere la cancellazione non autorizzata di dati aggiuntivi):

SELECT * FROM users WHERE userid = [id] AND password = [password]

Iniezione:

id = 1#
password = wrong_password

Payload: 2 caratteri

DoS

Gli attacchi DoS richiedono pochissimi caratteri. In un esempio di MySQL, occorrono 7 per la chiamata effettiva + x per i secondi specificati + tutto ciò che è necessario per poter chiamare la funzione e correggere la query.

Esempio:

SELECT * FROM users WHERE userid = [id]

Iniezione (questa è un'iniezione valida, una forma più lunga sarebbe 1 AND sleep(99) ):

sleep(99)

Payload: 9 caratteri

Lettura dei dati

Se i dati vengono visualizzati, la lunghezza dipende principalmente dal nome della tabella e della colonna. Assumerò il numero di colonne uguale per tutte le tabelle (potrebbe accadere e salva i caratteri).

Esempio:

SELECT * FROM comments WHERE commentid = [id]

Iniezione:

1 union select * from users

Payload: 27 caratteri.

Modifica dei dati

Anche le modifiche al database non autorizzate possono essere ottenute con pochi caratteri.

Esempio:

UPDATE users SET password = '[password]' WHERE id = [id]

Injection (into password):

',isadmin='1

Payload: 12 caratteri

Funzionerebbe anche un bypass di restrizione (il risultato è che tutte le password ora sono vuote *):

'#

Payload: 2 caratteri

* L'esempio della password è usato per semplicità; le password dovrebbero essere hash rendendo l'esempio impossibile. L'esempio si applica ancora a tutte le situazioni simili (aggiornamento di un nome utente, aggiornamento delle autorizzazioni e così via)

    
risposta data 28.02.2017 - 19:10
fonte
89

Senza contesto, presumo che l'autore si riferisca ai campi di input in un'applicazione client. L'esempio più semplice da utilizzare sarebbe un modulo in una pagina HTML in un'applicazione Web, anche se ciò che sto per descrivere è efficace praticamente per qualsiasi tipo di applicazione client.

Dato questo contesto, la risposta è no, non c'è una lunghezza massima del campo di input abbastanza breve da proteggerti dall'iniezione SQL, perché non controlli la lunghezza massima del campo di input . L'aggressore lo fa. Quando il modulo che contiene il campo di input risiede sul client (come in una finestra del browser sulla macchina dell'attaccante), si trova al di fuori del confine di fiducia e fuori dal tuo controllo. Può essere manipolato in qualsiasi modo l'attaccante desideri o abbia bisogno, o evitato completamente. Ricorda, per un'app Web, tutto ciò che ottieni è una richiesta HTTP. Non hai idea di come è stato creato, e non c'è motivo di credere che qualsiasi cosa tu abbia chiesto al browser di accadere realmente, che siano stati effettivamente eseguiti controlli di sicurezza sul lato client, che qualsiasi nella richiesta sia come hai inteso o in alcun modo sicuro.

Quindi no, la lunghezza del campo di input non è un meccanismo di prevenzione dell'iniezione SQL valido e mai, mai, fidarsi dell'input che attraversa un limite di sicurezza senza convalidarlo.

    
risposta data 28.02.2017 - 18:18
fonte
11

input fields as small as possible to reduce the likelihood of a hacker being able to squeeze SQL code into the field without it being truncated (which usually leads to a T-SQL syntax error).

IMHO, questa è solo merda. L'uso della lunghezza dei campi di input per la protezione da SQL injection è un consiglio terribile:

  • L'unico modo corretto di proteggere da SQL injection è l'uso di una dichiarazione preparata. I dati di input sono un parametro della query e non saranno mai utilizzati come testo SQL.
  • La dimensione di un campo deve essere controllata lato server perché non puoi mai fidarti di ciò che entra in una richiesta - potrebbe essere falsa - e dovrebbe essere usato per disinfettare i dati prima dell'utilizzo nel business livello o archiviazione del database.
  • Il consiglio di utilizzare qualsiasi cosa diversa dalle migliori pratiche è fonte di confusione per gli sviluppatori alle prime armi.
risposta data 28.02.2017 - 23:13
fonte
8

No.

Considera la query:

select * from tweets
WHERE RowNum >= [offset]
AND RowNum < [offset] + [limit]

Se potessi inserire un singolo non intero (ad esempio, la lettera "a") per offset , la query genererebbe un errore di sintassi e nessun messaggio mostrerebbe i tuoi "risultati non previsti dal progetto" requisito per causare danni. Se si può iniettare una stringa vuota si ottiene lo stesso effetto con un carico utile di lunghezza zero. Iniettare un commento finale sarebbe uno spreco di due caratteri;)

Un utente malintenzionato può sfruttare questo in un attacco denial of service (a differenza di un flooding della rete generalmente associato a DoS, ma ancora un DoS ). A seconda del servizio che viene negato, questo potrebbe essere catastrofico.

Come altre risposte suggeriscono che la lunghezza del campo non ha alcuna influenza sull'impatto dell'iniezione SQL. Le istruzioni parametrate e preparate sono la via da seguire, come indicato nel foglio Cheat di prevenzione dell'iniezione SQL di OWASP .

    
risposta data 28.02.2017 - 22:10
fonte
4

No.

Semplice esempio di un'iniezione SQL a un carattere:

'

Si genererebbe un errore che sarebbe un esempio di "restituzione dei risultati non previsti dal progetto". Molte volte gli errori possono essere utilizzati per ottenere informazioni utili in seguito in un exploit.

    
risposta data 01.03.2017 - 21:14
fonte
3

Sì.

La lunghezza massima è zero. L'unico modo per rendere sicuro l'input non attendibile tramite la lunghezza massima, senza altre convalide o verifiche, è di ignorare completamente l'input a partire dall'indice 0.

Ci sono molte altre (migliori) risposte qui, ma questo serve per rispondere alla domanda teorica su come stare al sicuro quando la lunghezza del campo è l'unico strumento a tua disposizione.

    
risposta data 02.03.2017 - 19:27
fonte
0

La lunghezza di un campo non avrà nulla a che fare con SQL injection, perché un tale attacco funziona semplicemente commentando il codice precedente e iniziando il codice di attacco, quindi la lunghezza di qualsiasi campo non avrà effetto su questa strategia.

    
risposta data 03.03.2017 - 00:47
fonte
0

C'è molta teoria qui ma nessun esempio reale. Quando ho trovato una vulnerabilità di sql injection real-world (ora applicata alle patch), ho provato a utilizzare campi di input lunghi circa 30 caratteri. Questo è stato molto frustrante perché mi ci è voluto un po 'per capire che ogni cosa dopo 30 personaggi è stata eliminata, e 30 personaggi non mi lasciavano spazio per molto.

(molti esempi di injection sql hanno un semplice sql "come select * dalla tabella dove id = @id", il mondo reale sql di solito sarà molto più complicato)

È possibile essere fantasiosi con il proprio input e un esperto di sql potrebbe probabilmente utilizzare alcuni trucchi per ridurre il conteggio del payload. Ma non importa quanto sei complicato se vuoi selezionare un nome di tabella lungo per cui avrai bisogno di molti caratteri.

Ad ogni modo, quando sono passato a usare un campo di input con oltre 1k di caratteri, ho trovato tutto questo per l'iniezione sql.

Detto questo, come molti commentatori sopra di me hanno detto, La migliore difesa contro l'iniezione sql è una dichiarazione preparata

    
risposta data 02.08.2018 - 17:38
fonte

Leggi altre domande sui tag