Questo codice impedisce l’iniezione SQL?

sfondo

Sono stato contattato per analizzare un Data Provider esistente e so che il seguente codice è difettoso; ma al fine di sottolineare quanto sia grave, ho bisogno di dimostrare che è suscettibile all’iniezione SQL.

Domanda

Quale parametro “Chiave” potrebbe interrompere la funzione PrepareString e consentirmi di eseguire un’istruzione DROP ?

Snippet di codice

 Public Shared Function GetRecord(ByVal Key As String) As Record Dim Sql As New StringBuilder() With Sql .Append("SELECT * FROM TableName") If String.IsNullOrEmpty(Agency) Then .Append(" ORDER BY DateAdded") Else .Append(" WHERE Key = '") .Append(PrepareString(Key)) .Append("'") End If End With Return ExecuteQuery(Sql.ToString()) End Function Public Shared Function PrepareString(ByVal Value As String) As String Return Value.Replace("''", "'") _ .Replace("'", "''") _ .Replace("`", "''") _ .Replace("´", "''") _ .Replace("--", "") End Function 

In risposta alla tua domanda diretta: questo codice impedisce l’iniezione SQL: No

Ecco la prova: spingere questa stringa attraverso il metodo PrepareString:

 Dim input = "'" & Chr(8) & "; Drop Table TableName; - " & Chr(8) & "-" Dim output = PrepareString(input) Console.WriteLine(input) Console.WriteLine(output) 

Ho modificato il metodo GetRecord che hai postato per restituire la stringa SQL completamente preparata anziché ottenere il record dal database:

 Console.WriteLine(GetRecord(output)) 

E questo è l’output

 Input = ; Drop Table TableName; -- Output = '; Drop Table TableName; -- Query = SELECT * FROM TableName WHERE Key = ''; Drop Table TableName; --' 

Aggiungi 1 riga di codice aggiuntiva:

 My.Computer.Clipboard.SetText(input) 

E hai la stringa che devi copiare direttamente negli Appunti per incollare nel campo di immissione sul sito Web per completare l’iniezione SQL:

 '; Drop Table TableName; - - 

[Notando che i caratteri di controllo sono stati omessi dall’output di Post di StackOverflow, quindi dovrai seguire l’esempio di codice per creare l’output]

Dopo che il metodo PrepareString è stato eseguito, avrà lo stesso output: il codice ASCII Chr (8) è il backspace che rimuoverà il “” extra che si sta aggiungendo alla mia, che chiuderà la stringa e quindi io libero di aggiungere tutto ciò che voglio alla fine. Il tuo PrepareString non vede il mio – perché sto effettivamente usando – – con un carattere backspace per rimuovere lo spazio.

Il codice SQL risultante che stai creando eseguirà quindi la mia istruzione Drop Table senza impedimenti e prontamente ignorerà il resto della tua query.

La cosa divertente di questo è che puoi usare caratteri non stampabili per bypassare praticamente qualsiasi controllo dei caratteri che puoi inventare. Quindi è più sicuro usare query parametrizzate (che non è quello che hai chiesto, ma è il modo migliore per evitarlo).

Per rispondere alla tua domanda discutibile, no, non funzionerebbe.

.Replace("``", "''") impedirebbe le query legittime con ‘`’

.Replace("´", "''") impedirebbe le query legittime con’ ”

.Replace("--", "") impedirebbe le query legittime con ‘-‘ in esse

.Replace("''", "'") modificherebbe erroneamente le query legittime con’ ” ‘in esse

e così via.

Inoltre, l’intero set di caratteri di escape può variare da un RDBMS a un altro. Domande parametriche FTW.

Penso che sia inaccessibile se si sostituisce semplicemente “con”. Ho sentito che è ansible modificare il carattere di citazione di fuga, che potrebbe potenzialmente rompere questo, tuttavia non sono sicuro. Penso che tu sia al sicuro però.

Penso che sia sicuro (almeno in SQL server), e penso anche che l’unica cosa che devi fare è s = s.Replace("'", "''") . Ovviamente dovresti usare query parametrizzate, ma lo sai già.

Questo articolo MSDN copre la maggior parte delle cose che devi cercare (ho paura di dire tutto quando si tratta di SQL injection).

Ma risponderò ai sentimenti dei parametri dei parametri di tutti gli altri.

Per quanto riguarda il tuo esempio alcuni trucchi [Modifica: Aggiornato questi]:

  • la stringa “1 OR 1 = 1” non consentirebbe all’utente di recuperare tutto

  • o peggio “1; drop table sometablename”

Secondo l’articolo che vuoi controllare:

; – Delimitatore di query.

‘- Delimitatore stringa dati carattere.

– – Delimitatore di commenti.

/ * … / – Delimitatori di commenti. Il testo tra / e * / non viene valutato dal server.

xp_ – Usato all’inizio del nome delle stored procedure estese dal catalogo, come xp_cmdshell.

Stai tentando di aggiungere una lista nera ai personaggi per implementare la tua versione di SQL Escaping. Suggerirei di rivedere questo URL : l’escape di SQL non è necessariamente la scelta peggiore (ad esempio, correggere rapidamente le app esistenti) ma deve essere fatto bene per evitare vulnerabilità.

Tale URL collega a un’altra pagina per l’escape in SQL Server in cui l’autore fornisce suggerimenti che consentono di evitare le vulnerabilità senza limitare la funzionalità.

Se aiuta, gli articoli suggeriscono anche di evitare le parentesi graffe (le chiamo parentesi quadre – ma []).

Se si tenta di utilizzare il proprio codice, alcuni potrebbero passare una chiave (; selezionare * dalla tabella e ottenere un elenco di qualsiasi tabella che desiderano.

Nel tuo codice non stai controllando il punto e virgola che ti consente di terminare un’istruzione t-sql e avviarne un’altra.

Vorrei andare con una query parametrizzata.