Frage

Hintergrund

Ich habe vertraglich einen vorhandenen Data Provider zu analysieren und ich weiß, dass der folgende Code fehlerhaft ist; sondern um darauf zu hinweisen, wie schlimm es ist, ich muss beweisen, dass es eine SQL-Injection anfällig ist.

Frage

Was „Key“ Parameter könnte die PrepareString Funktion brechen und erlauben Sie mir eine DROP Anweisung auszuführen?

Code-Snippet

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
War es hilfreich?

Lösung

In Antwort auf Ihre direkte Frage: Ist dieser Code verhindert SQL-Injection: Nein

Hier ist der Beweis - drücken Sie diese Zeichenfolge durch die PrepareString Methode:

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

Console.WriteLine(input)
Console.WriteLine(output)

I modifiziert, um die GetRecord Methode der vollständig vorbereitete SQL-Zeichenfolge zurück geschrieben, anstatt den Datensatz aus der Datenbank zu erhalten:

Console.WriteLine(GetRecord(output))

Und das ist der Ausgang

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

1 zusätzliche Codezeilen:

My.Computer.Clipboard.SetText(input)

Und Sie haben die Zeichenfolge, die Sie direkt in der Zwischenablage kopiert müssen bekommen in Ihr Eingabefeld auf der Website einfügen SQL-Injektion beenden:

'; Drop Table TableName; - -

[Anbetracht dessen, dass die Steuerzeichen haben aus dem Postausgang von Stackoverflow weggelassen, so dass Sie den Code Beispiel folgen müssen, um die Ausgabe erstellen]

Nach der PrepareString Methode ausgeführt wird, wird es genau die gleiche Ausgabe hat - die Chr (8) ASCII-Code ist die Rück, die die extra „'“ werden entfernen, dass Sie zu mir gehörst anhängen, die die Zeichenfolge schließen und dann ich bin frei zu addieren, was ich am Ende will. Ihr PrepareString sieht nicht meinen -, weil ich eigentlich mit - -. Mit einem Backspace Charakter, den Raum zu entfernen

Den resultierenden SQL-Code, Sie bauen dann meinen Drop Table Anweisung ungehindert ausführen und prompt den Rest Ihrer Abfrage ignorieren.

Der Spaß daran ist, dass Sie nicht druckbare Zeichen verwenden können, um grundsätzlich alle Zeichen umgehen überprüfen Sie erfinden. So ist es am sichersten parametrisierte Abfragen zu verwenden (das ist nicht das, was Sie gefragt, aber es ist der beste Weg, dies zu vermeiden).

Andere Tipps

Um Ihre fragwürdige Frage zu beantworten, keine würde es nicht funktionieren.

.Replace("``", "''") würde verhindern, dass legitime Anfragen mit '`'

.Replace("´", "''") würde verhindern, dass legitime Anfragen mit '''

.Replace("--", "") würden legitime Anfragen mit verhindern '-' in ihnen

.Replace("''", "'") würde legitime Anfragen falsch ändern mit '' '' in ihnen

und so weiter.

Darüber hinaus ist die vollständige Reihe von Escape-Zeichen von einem RDBMS zum anderen variieren kann. Parametrisierte Abfragen FTW.

Ich denke, es unhackable ist, wenn man nur ersetzen 'mit ‚‘. Ich habe gehört, dass es möglich ist, die Flucht Anführungszeichen zu ändern, die diese möglicherweise brechen könnte, aber ich bin mir nicht sicher. Ich glaube, Sie sind sicher aber.

Ich denke, es (zumindest in SQL Server) sicher ist, und ich denke, auch das einzige, was Sie wirklich tun müssen, ist s = s.Replace("'", "''"). Natürlich sollten Sie parametrisierte Abfragen verwenden, aber Sie bereits wissen.

Der MSDN-Artikel die meisten Sachen, decken Sie müssen halten sie Ausschau nach (ich habe Angst, alles zu sagen, wenn es um SQL-Injection kommt).

Aber ich werde echo allen anderen Gefühl der Parameter Parameter Parameter.

Wie bei Ihrem Beispiel einige gotchas [Edit: Aktualisiert diese]:

  • wäre nicht die Zeichenfolge "1 OR 1 = 1" ermöglicht es dem Benutzer, um alles zurück

  • oder schlechter "1; drop table sometablename"

Nach dem Artikel, den Sie für die überprüfen möchten:

  

; -. Query-Begrenzer

     

‘-. Zeichendaten Zeichenfolgebegrenzer

     

- -. Comment Begrenzer

     

/ * ... / - Kommentar Begrenzer. Text   zwischen / und * / wird nicht ausgewertet durch   der Server.

     

xp_ - Gebraucht am Anfang des Namens   Katalog-erweiterte gespeicherte Prozeduren,   wie xp_cmdshell.

Sie versuchen, auf schwarze Liste Zeichen Ihre eigene Version von SQL Escaping zu implementieren. Ich würde vorschlagen, bewerten die diese URL - SQL Entkommen ist nicht unbedingt die schlechteste Wahl (dh schnell Festsetzung bestehenden Anwendungen), aber es muss richtig Schwachstellen zu vermeiden, durchgeführt werden.

Diese URL-Links zu andere Seite in SQL Server zu entkommen, wo der Autor Vorschläge gibt, die Sie ohne Funktionalität Begrenzung Schwachstellen zu vermeiden.

Wenn es hilft, schlagen die Artikel Klammern zu entkommen (Ich nenne sie eckige Klammern - aber [])

.

Wenn Sie versuchen, Ihren Code zu verwenden, um einige man einen Schlüssel passieren könnte (; select * from Tabelle,. Und erhält eine Liste, was immer sie wollen Tabelle

In Ihrem Code Ihrer nicht für die Semikolon Überprüfung, die Sie Anweisung Ende einer T-SQL läßt und eine anderen starten.

würde ich mit einer parametrisierten Abfrage gehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top