Domanda:
Esiste una lunghezza del campo troppo breve per consentire un'iniezione SQL dannosa?
James Jenkins
2017-02-28 22:18:55 UTC
view on stackexchange narkive permalink

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

campi di input più piccoli possibile per ridurre la probabilità che un hacker sia in grado di spremere il codice SQL nel campo senza che venga troncato (il che di solito porta a un errore di sintassi T-SQL).

Fonte: Microsoft SQL Server 2008 R2 Unleashed

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

Poiché il danno è la modifica del database o la restituzione di risultati non previsti dalla progettazione. Includere un indicatore di fine commento ( - ) in un campo di due caratteri non causerebbe danni, causerebbe solo una query fallita. Il potenziale hacker potrebbe apprendere che il campo è suscettibile di iniezione, ma non è in grado di sfruttarlo.

Se l'errore fornito è dettagliato, potrebbe essere sufficiente per ottenere informazioni utili, soprattutto se uno sviluppatore ha trattato i nomi delle tabelle come "segreti" ...
SQL Injection non viene sempre eseguito su un campo di input: puoi scegliere come target clausole orderby negli URL, ad esempio in cui potresti eseguire sql dannoso.La dimensione limitata di un campo non lo fermerà.
@iain: Buon punto.Inoltre, limitare la lunghezza dei campi per (presumo) i dati del modulo HTML ricevuti non mi sembra un buon modo per evitare l'iniezione di sql.L'elusione di SQL injection è fondamentalmente un problema risolto;lascia che sia la libreria di connessione al database a gestirlo utilizzando istruzioni preparate con segnaposto, invece di incollare query utilizzando le funzioni di stringa del tuo linguaggio di programmazione e sbagliare perché hai dimenticato di proteggerti dalla scappatoia numero 59654.
@Pascal "* L'elusione di SQL injection è fondamentalmente un problema risolto; *" si applica solo al nuovo codice dove sono state applicate le considerazioni appropriate.C'è molto codice esistente in cui il problema non è stato risolto.Presumibilmente c'è una lunghezza del carattere al di sotto della quale affrontare i problemi esistenti è meno urgente rispetto a quelli con lunghezze maggiori.
Sono l'unico che pensa che quel libro dovrebbe essere bruciato pubblicamente?Le query parametrizzate esistono da così tanto tempo che l'autore mi porta a credere che non abbiano nemmeno la metà di quello di cui stanno parlando.Sembra che abbiano copiato + incollato spazzatura da una raccolta di blog e pubblicato un libro.Potrebbero anche dirti che dovresti esercitarti a sparare con proiettili più piccoli in modo da poter aumentare l'immunità ai proiettili più grandi.
@MonkeyZeus Questa è più la regola che l'eccezione per i libri tecnici.Quando professionisti non addetti alla sicurezza offrono consigli sulla sicurezza, spesso è di scarsa qualità.
Che ne dici di 0 caratteri?E solo se convalidato sul server.
@Xander Questa affermazione mi causa molta angoscia.Certamente non sono nemmeno un esperto di sicurezza, ma il mio unico paragrafo probabilmente decima tutto ciò che quel libro ha da offrire.Immagino che [Argomento dall'ignoranza] (https://en.wikipedia.org/wiki/Argument_from_ignorance) abbia ancora una popolarità insondabile.L'unica minuscola grazia salvifica possibile per quel libro sarebbe se la parametrizzazione non fosse supportata in quella versione di SQL Server.Inoltre, se questa è la regola più che l'eccezione, avremo un bel fuoco potente.
@MonkeyZeus Sono d'accordo sul fatto che sia angosciante, ma ho creato un hobby per rivedere i consigli sulla sicurezza nei libri tecnici e nei libri di programmazione in particolare.La copertura è generalmente abissale o completamente assente.Ad esempio, ho un libro sulla creazione di sistemi di e-commerce da zero che discute brevemente dell'uso di HTTPS e poi dichiara che ulteriori discussioni sulla sicurezza erano "al di fuori dello scopo" del libro.
@Xander Direi che "guarda altrove" è più nobile che affermare sfacciatamente qualcosa come "Offuscare i dati del modulo utilizzando JavaScript e una chiave casuale generata dal server prima di inviare i dati al server".Almeno quel libro di e-commerce dice "Ehi ragazzo, non vogliamo che il tuo server venga schiacciato con un fallo di carta vetrata, quindi se ti interessa la sicurezza, procurati un buon libro al riguardo. Il nostro libro ti insegna semplicemente come creare un e-commerce site, non come proteggerne uno. "
Sono contro la masterizzazione di libri per principio - ma voterei per riportare le scorte per gli autori - "che di solito porta a un errore di sintassi T-SQL" - il punto centrale di SQL Injection è far interagire i dati inviati con illimiti della destinazione prevista.
Come per altre risposte, le lunghezze dei campi brevi non prevengono i problemi.Recentemente ho lavorato su un'applicazione legacy con un campo nome utente di 8 caratteri (e 8 caratteri sono stati controllati nel codice), ma era ancora aperta all'iniezione SQL.Le cose sono peggiorate quando il campo della password è stato utilizzato anche nell'iniezione.
Sebbene sia d'accordo al 100% su quanto male questi problemi di sicurezza siano solitamente affrontati e su quanto sia pessimo il consiglio di quel libro, penso che quel consiglio sia cattivo principalmente perché è molto probabile che permetta alle persone di illudersi nel pensare che prendendo quella "precauzione"si sono protetti contro l'iniezione SQL, ed è anche un male perché incoraggia a perseguire la riduzione del rischio in un caso in cui l'eliminazione del rischio sarebbe possibile (e facile).Non c'è modo di negare che quella citazione non pretenda di impedire l'iniezione di SQL;afferma solo di "ridurre la probabilità" (che è sciocco e fuorviante).
@MonkeyZeus Molte API DB * ancora * non supportano i parametri con valori di array, come quelli per il lato destro dell'operatore "IN".Per aggirare questo problema, devi includere un numero variabile di parametri in una query, a quel punto finisci per "incollare" un elenco di segnaposto e mantenere l'ordine dei segnaposto posizionali (`?`) Sincronizzato tra le istruzionie l'array di valori è difficile come sfuggire.
Otto risposte:
Xander
2017-02-28 23:18:13 UTC
view on stackexchange narkive permalink

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

Dato questo contesto, la risposta è no, non esiste una lunghezza massima del campo di input sufficientemente breve da proteggerti da SQL injection, perché non controlli la lunghezza massima del campo di input . L'attaccante lo fa. Quando il modulo contenente il campo di input si trova sul client (come in una finestra del browser sulla macchina dell'aggressore) è al di fuori del limite di fiducia e fuori dal tuo controllo. Può essere manipolato in qualsiasi modo l'aggressore vuole o ha bisogno, o evitato completamente. Ricorda, per un'app Web, tutto ciò che ottieni è una richiesta HTTP. Non hai idea di come sia stato creato e non hai motivo di credere che tutto ciò che hai chiesto di fare al browser sia realmente accaduto, che qualsiasi controllo di sicurezza lato client sia stato effettivamente eseguito, che qualsiasi cosa nella richiesta sia come inteso o in alcun modo sicuro.

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

è una buona risposta, forse l'autore significa che un campo troppo corto riduce la probabilità di ottenere informazioni dai database, ma non può evitare un danno da una SQL Injection, ad esempio, `o 1 = 1` può causare gravi danni.
@hmrojas.p Non lo fa, perché una lunghezza massima archiviata in ingresso non impedisce effettivamente a un utente malintenzionato di inviare tutti i dati che desidera in quel campo.Posso impostare una lunghezza massima di input su 3 e un utente malintenzionato potrebbe comunque inviare o 1 = 1; eliminare gli utenti della tabella; - Se non controlli sul lato server, non c'è nulla che lo impedisca.
Sì, sono d'accordo, stavo supponendo che ci fosse una convalida della lunghezza sul lato server, voglio dire che il tipo di SQL Injection (`o 1 = 1`) potrebbe influenzare una query SQL come UPDATE o DELETE, potrebbe rompere l'integrità dei dati,anche se si dispone di una convalida della durata lato server, questa misura è complementare.
Allora, cosa succede se il server esegue quella convalida allora.Gli utenti dannosi non possono toccarlo.Se il mio script PHP utilizza solo fino ai primi x caratteri (che è estremamente semplice da fare e potrebbe essere fatto nel mezzo della query), allora cosa?
@Ryan Questa è in effetti la chiave.* Quello * sarebbe il controllo di sicurezza.L'impostazione della lunghezza massima del campo di input è utile per l'UX, ma non ha alcun valore di sicurezza.È la convalida dell'input lato server che fornisce la sicurezza.Questa è una distinzione fondamentale e importante.È una distinzione teorica poiché la risposta corretta è utilizzare query parametrizzate, ma guardando strettamente alla gestione degli input, è ancora una distinzione importante.
Ho downvoted perché questo presume che la lunghezza del campo non sia convalidata sul lato server.Sebbene sia d'accordo sul fatto che qualsiasi risposta dovrebbe menzionare che la lunghezza deve essere convalidata dal lato server e al di fuori del controllo dell'utente per essere di qualsiasi utilità, credo che la convalida della lunghezza dal lato server invaliderebbe completamente l'intera risposta.(La risposta potrebbe essere ancora no, ma non per questo motivo.)
@jpmc26 Che sia convalidato sul lato server è irrilevante.Il contesto dell'offerta è una misura di "sicurezza" lato client e la convalida lato server non viene affrontata.
@Xander L'unica persona che ha assunto la convalida solo lato client qui sei tu.Non vedo nulla nella domanda o nei commenti che suggerisca che questa sia la situazione che il PO sta descrivendo.
@jpmc26 Dalla domanda: * "campi di input più piccoli possibile" *.Il server sa cos'è un campo di input quando riceve una risposta?Voglio dire, se invii un modulo HTML, il server non ha il concetto di "campo di input".Riceve solo i dati.Penso che senza il contesto del libro, la citazione è piuttosto ambigua.
@JacobAlvarez Il server ovviamente sa quali sono gli input e può discernere i valori se può inserirli in una query SQL in cui può avvenire l'iniezione.Se può discernere i valori, può determinare la lunghezza.Non fraintendermi;la citazione non ha senso.Ma lo è anche inventare ragioni non correlate sul perché non ha senso, quindi cerchiamo di ottenere le ragioni giuste.
@jpmc26, la citazione dice "campo di input".È qui che avviene l'interazione dell'utente.Quindi è chiaro per me che si tratta del lato client, non del lato server.Lo stesso vale per i moduli che eseguono la convalida dell'input JS.A meno che non sia * esplicitamente dichiarato * che la convalida viene * ripetuta * lato server, è lecito ritenere che la convalida lato server sia inesistente.
@aross Per quanto ne sappiamo, potremmo parlare di un'interfaccia REST che non fornisce nemmeno una GUI."Campo di immissione" per me non significa altro che il valore generato dall'utente.Menzionare che la convalida della lunghezza deve essere eseguita in un ambiente non controllato dall'utente è decisamente appropriato.Supponendo che non accada e facendo in modo che la base di una * intera * risposta sia in realtà solo evitare di rispondere alla domanda.
@jpmc26 Sembra che tu stia combinando i parametri con i campi di input.
@aross Mi sembra di pensare al fatto che i valori di questi "campi di input" finiscono * in una query SQL *.Non vi è alcuna differenza pratica e il "campo di input" non è definito rigorosamente.L'idea che questa sia una convalida solo lato client è un * presupposto completamente ingiustificato * degno di nient'altro che una nota a margine.Non risponde * niente * alla domanda se la lunghezza sia importante nel contesto di SQL injection.
Bene, se stiamo iniziando una discussione sulla semantica, ecco alcune fonti: [input] (https://en.wikipedia.org/wiki/Input_ (computer_science)), [parametro] (https: //en.wikipedia.org / wiki / Parameter_ (computer_programming))
Cerchiamo di [continuare questa discussione in chat] (http://chat.stackexchange.com/rooms/54700/discussion-between-jpmc26-and-aross).
tim
2017-03-01 00:10:54 UTC
view on stackexchange narkive permalink

No, non esiste una lunghezza troppo breve per essere sfruttabile (almeno in alcune situazioni).

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

Un filtro di lunghezza è comunque una buona misura come difesa in profondità (così come i filtri interi, i filtri alfa, ecc.). Ci sono molte situazioni in cui ad es. un input valido non potrebbe mai essere superiore a 30 caratteri, ma dove uno sfruttamento significativo richiede di più. Dovrebbe (ma probabilmente non lo è) essere ovvio che qualsiasi filtraggio come difesa in profondità deve avvenire lato server poiché qualsiasi cosa lato client può essere semplicemente aggirata.

Bypass restrizione

Le clausole di restrizione (ad esempio AND / OR ) possono essere ignorate da due caratteri, il che può causare danni reali, non solo una query fallita. L'esempio più semplice è un accesso (altri esempi sarebbero l'eliminazione 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 MySQL, sono necessari 7 per la chiamata effettiva + x per i secondi dati + tutto ciò che è necessario per poter chiamare la funzione e correggere la query.

Esempio:

  SELECT * FROM users WHERE userid = [id]  

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

  sleep (99)  

Payload: 9 caratteri

Lettura dati

Se i dati viene visualizzato, la lunghezza dipende principalmente dal nome della tabella e della colonna. Presumo che il conteggio delle colonne sia uguale per tutte le tabelle (può succedere e salva i caratteri).

Esempio :

  SELEZIONA * DA commenti WHERE commentid = [id]  

Iniezione:

  1 unione seleziona * dagli utenti  

Payload: 27 caratteri.

Modifica dati

È anche possibile apportare modifiche non autorizzate al database con pochi caratteri.

Esempio:

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

Iniezione (nella password):

  ', isadmin =' 1  

Payload: 12 caratteri

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

  '#  

Payload: 2 caratteri

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

"Un filtro di lunghezza non è una protezione valida contro SQL injection e le istruzioni preparate sono davvero l'unica difesa adeguata." Questa è l'unica risposta valida.SQL senza istruzioni preparate mi ricorda ["Strategie su come cavalcare un cavallo morto"] (http://www.deadhorses.org/)
Buona fortuna nella preparazione di un'istruzione con un numero variabile di segnaposto, come il lato destro dell'operatore "IN".
@DamianYerrick Penso che sia un'ipotetica difettosa.Perché dovresti fornire all'utente finale infinite combinazioni di segnaposto per una clausola `IN`?È abbastanza facile avere una manciata di modelli che consentono 1..n (per una piccola n).
In "SELECT * FROM users WHERE userid = [id]" puoi inserire a se a è il nome di una colonna, quindi hai un'iniezione di solo 1 carattere.
@ShawnC Il caso d'uso è che un utente inserisce un elenco di elementi da interrogare.Per prima cosa, quanto è grande "una piccola n"?Sembrerebbe violare la regola di zero uno infinito.In secondo luogo, se sono presenti due diversi campi di input con valori di elenco, ora è necessario memorizzare e testare i modelli O (n ^ 2).
@Alexander: Si noti che non è sempre possibile utilizzare istruzioni preparate poiché non possono parametrizzare i nomi dei campi.E quando devi costruire i tuoi join dall'input dell'utente, il tuo lavoro è diventato molto più difficile ...
@Joshua Questi sono casi speciali,> 99% delle query non parametrizzate può essere parametrizzato senza troppi problemi.E per i casi speciali, imporre che i nomi dei campi debbano aderire a "[a-zA-Z] +" è molto più semplice che consentire determinati caratteri speciali nei valori e non consentirne altri.Fatti divertenti: quando sono passato alle query parametrizzate in PHP, il problema principale era trovare un provider che avesse mysqli abilitato.[Il mio problema principale in DotNet era la clausola `IN`.] (Http://stackoverflow.com/questions/20143012/sqlparameter-and-in-statement)
@Alexander: C'è qualche problema di sicurezza con il run-time che genera una query del formato `SELECT [qualunque] da MyTable dove id = @ @p0 OR id = @ @p1 OR id = @ @p2` per qualsiasi numero di parametri immessi dall'utente, se nessunodel testo dei parametri è incluso nella dichiarazione?
Serge Ballesta
2017-03-01 04:13:06 UTC
view on stackexchange narkive permalink

campi di input più piccoli possibile per ridurre la probabilità che un hacker sia in grado di spremere il codice SQL nel campo senza che venga troncato (il che di solito porta a un errore di sintassi T-SQL).

IMHO, questa è solo una merda. Usare la lunghezza dei campi di input per proteggere dall'SQL injection è un pessimo consiglio:

  • L'unico modo corretto per proteggere dall'SQL injection è l'uso di un'istruzione preparata. I dati di input sono un parametro della query e non verranno mai utilizzati come testo SQL.
  • La dimensione di un campo deve essere controllata lato server perché non puoi mai fidarti di ciò che viene fornito in una richiesta - potrebbe essere contraffatta - e dovrebbe essere utilizzato per disinfettare i dati prima dell'uso nel livello aziendale o nell'archiviazione del database.
  • Consiglio di utilizzare qualcosa di diverso dalle best practice crea confusione per gli sviluppatori alle prime armi.
benrifkah
2017-03-01 03:10:19 UTC
view on stackexchange narkive permalink

Considera la query:

  seleziona * da tweetsWHERE RowNum > = [offset] AND RowNum < [offset] + [limit]  

Se potessi inserire un singolo non intero (ad esempio, la lettera "a") per offset , la query risulterebbe in una sintassi errore e nessun post verrebbe visualizzato dando il tuo requisito "risultati non previsti dalla progettazione" per causare danni. Se puoi iniettare una stringa vuota, ottieni lo stesso effetto con un payload di lunghezza zero. Inserire un commento finale sarebbe uno spreco di due caratteri;)

Un utente malintenzionato può sfruttare questo in un attacco Denial of Service (diversamente da un allagamento di rete generalmente associato a DoS, tuttavia ancora un DoS). A seconda del servizio negato, ciò potrebbe essere catastrofico.

Poiché altre risposte suggeriscono che la lunghezza del campo non ha alcuna incidenza sull'impatto di SQL injection. Le istruzioni preparate e parametrizzate sono la strada da percorrere come indicato nel Cheat Sheet di OWASP SQL Injection Prevention.

Denial of service e SQL injection sono due cose molto diverse.Questa risposta non offre nulla di utile che non sia già stato affrontato nelle risposte esistenti.
Esatto, SQL injection è una forma della categoria "injection attack", che può produrre molti scopi diversi, incluso il Denial of Service.Denial of service è una tecnica che può essere ottenuta attraverso diversi vettori.Uno comune è tramite un'inondazione distribuita.Tuttavia, qualsiasi tecnica che produca un servizio che non risponde è correttamente classificata come attacco di tipo Denial of Service.Questo può includere SQL injection.La mia risposta fornisce una spiegazione di come questo può essere fatto con zero caratteri.Fornisce inoltre un collegamento al Cheat Sheet OWASP sulla prevenzione delle iniezioni SQL.Grazie per aver sottolineato che dovrei evidenziarli.
MikeSchem
2017-03-02 02:14:18 UTC
view on stackexchange narkive permalink

No.

Semplice esempio di iniezione SQL di un carattere:

  ` 

Sarebbe generato un errore sarebbe un esempio di "restituzione di risultati non previsti dalla progettazione". Molte volte gli errori possono essere utilizzati per ottenere informazioni che aiuteranno in seguito in un exploit.

Forse potresti aggiungere una spiegazione su come quell'iniezione potrebbe essere dannosa?
Sarebbe un errore che sarebbe un esempio di "restituzione di risultati non previsti dalla progettazione" Molte volte gli errori possono essere utilizzati per ottenere informazioni che aiuteranno in seguito in un exploit.
Grazie!Mi sono preso la libertà di includere la tua spiegazione nella risposta.
Dan
2017-03-03 00:27:35 UTC
view on stackexchange narkive permalink

Sì.

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

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

Onestamente non sono convinto che un attaccante abbastanza intelligente non possa gestire un attacco con zero caratteri.
Sulla falsariga di altri commenti sopra - dove qualsiasi risultato non previsto dalla progettazione è una qualche forma di SQL injection;sarebbe anche valido dire che qualsiasi comportamento non previsto dalla progettazione è una forma di Sql injection (facendo riferimento all'esempio sleep (60) sopra .. che era piuttosto interessante :)? Una SQL injection di lunghezza 0 quindi, non dovrebbe necessariamente coinvolgere alcun SQL .... fintanto che si potrebbe legare la connessione ??
@Dan beh, accidenti se sapessi che andrei avanti e farei una contromisura.Questo è il problema con la sicurezza in generale ... Pensiamo che sia sicuro fino a quando qualche utente malintenzionato non dimostra che non lo è.
Spencer Williams
2017-03-03 05:47:59 UTC
view on stackexchange narkive permalink

La lunghezza di un campo non avrà nulla a che fare con l'iniezione SQL, perché un attacco di questo tipo funziona semplicemente commentando il codice precedente e avviando il codice di attacco, quindi la lunghezza di qualsiasi campo non avrà effetto su questa strategia.

Penso che il punto di OP sia che l'applicazione non consentirà a una quantità arbitraria di testo di raggiungere il database: viene comunque troncato a una lunghezza particolare.
Almenon
2018-08-02 20:38:10 UTC
view on stackexchange narkive permalink

C'è molta teoria qui ma nessun vero esempio. Quando ho trovato una vulnerabilità di sql injection nel mondo reale (ora corretta), ho provato a utilizzare campi di input lunghi circa 30 caratteri. Questo è stato molto frustrante perché mi ci è voluto un po 'per capire che tutto dopo 30 caratteri era stato eliminato e 30 caratteri non mi lasciavano molto spazio.

(molti esempi di sql injection hanno sql semplice "come select * from table dove id = @id", sql del mondo reale di solito sarà molto più complicato)

Puoi ottenere fantasia con il tuo input e un esperto di sql potrebbe probabilmente utilizzare alcuni trucchi per ridurre il conteggio del carico utile. Ma non importa quanto tu sia difficile se vuoi selezionare un nome di tabella lungo, avrai bisogno di molti caratteri per questo.

Comunque, quando sono passato a utilizzare un campo di input con oltre 1k caratteri Ho trovato molto per sql injection.

Detto questo, come molti commentatori sopra di me hanno detto, la migliore difesa contro sql injection sono le dichiarazioni preparate



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...