Domanda

Sfondo

Sono stato incaricato di analizzare un fornitore di dati esistente e so che il codice seguente è difettoso; ma per sottolineare quanto sia grave, devo dimostrare che è suscettibile all'iniezione di SQL.

Domanda

Cosa " Chiave " Il parametro 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
È stato utile?

Soluzione

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

Ecco la prova - invia 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 pubblicato 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 incollarla nel campo di input sul sito Web per completare l'iniezione SQL:

'; Drop Table TableName; - -

[Notando che i caratteri di controllo sono stati omessi dall'output post da StackOverflow, quindi dovrai seguire l'esempio di codice per creare il tuo output]

Dopo l'esecuzione del metodo PrepareString, avrà lo stesso identico output: il codice ASCII Chr (8) è lo spazio posteriore che rimuoverà l'extra " '" che stai aggiungendo al mio che chiuderà la tua stringa e poi sono libero di aggiungere quello 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à la mia istruzione Drop Table senza ostacoli e ignorerà prontamente il resto della tua query.

La cosa divertente di questo è che puoi usare caratteri non stampabili per aggirare praticamente qualsiasi controllo di carattere che puoi inventare. Quindi è più sicuro usare query con parametri (che non è quello che hai chiesto, ma è il percorso migliore per evitarlo).

Altri suggerimenti

Per rispondere alla tua domanda discutibile, no non funzionerebbe.

.Replace (" `` " ;, " '' ") impedirebbe query legittime con '' '

. Sostituisci (" & # 180; " ;, " '' ") impedirebbe legittime query con '& # 180;'

.Replace (" - " ;, " ") impedirebbe legittime query con '-' in loro

.Replace (" '' " ;, " '") modifica 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. Query con parametri FTW.

Penso che sia inamovibile se si sostituisce semplicemente 'con' '. Ho sentito che è possibile cambiare il carattere della citazione di escape, che potrebbe potenzialmente spezzarlo, tuttavia non ne sono sicuro. Penso che tu sia al sicuro.

Penso che sia sicuro (almeno in SQL Server) e penso anche che l'unica cosa che devi effettivamente fare sia s = s.Replace (" '" ;, "' '") . Ovviamente dovresti usare query con parametri, ma lo sai già.

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

Ma farò eco al sentimento di tutti gli altri dei parametri parametri parametri.

Come nel tuo esempio alcuni gotchas [Modifica: Aggiornato questi]:

  • non sarebbe la stringa " 1 OR 1 = 1 " consentire all'utente di recuperare tutto

  • o peggio " 1; elimina la tabella sometablename "

Secondo l'articolo che si desidera verificare:

  

; - Delimitatore di query.

     

'- Delimitatore della stringa di dati di carattere.

     

- - Delimitatore di commenti.

     

/ * ... / - Delimitatori di commenti. Testo   tra / e * / non viene valutato da   il server.

     

xp_ - Utilizzato all'inizio del nome di   stored procedure estese dal catalogo,   come xp_cmdshell.

Stai cercando di inserire nella black list i caratteri per implementare la tua versione di SQL Escaping. Suggerirei di rivedere questo URL - L'escaping di SQL non è necessariamente la scelta peggiore (ovvero rapidamente correzione di app esistenti) ma deve essere fatto correttamente per evitare vulnerabilità.

L'URL si collega a altro pagina per la fuga 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 sfuggire alle parentesi graffe (le chiamo parentesi quadre - ma []).

Se provi ad usare il tuo codice qualcuno potrebbe passare una chiave (; seleziona * dalla tabella; e ottieni un elenco di qualunque tabella desideri.

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

Vorrei andare con una query con parametri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top