SQL Abfrage mit Sonderzeichen - SQL Injection verhindern

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    SQL Abfrage mit Sonderzeichen - SQL Injection verhindern

    Hallo,

    ich habe eine Access-DB in der ich diverse Texte speicher. Diese Texte besitzen von Zeilenumbruch bis zum Apostroph alle Zeichen.
    Nun machen mir diese krummen Strings logischerweise die Abfrage kaputt... Wie umgehe ich das?

    Mein Code:

    VB.NET-Quellcode

    1. Dim objConnection As OleDb.OleDbConnection = New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; " & "Data Source=C:\Datenbank\datenbank.accdb")
    2. Dim objDataAdapter As OleDb.OleDbDataAdapter
    3. Dim objDataSet As DataSet
    4. Dim objDataView As DataView
    5. Sub blabla
    6. dim test as string
    7. test = "INSERT INTO d_datenbank (neu, ueberschrift, inhalt, Datum, link) VALUES (false, '" & ueberschrift(counter) & "', '" & _
    8. inhalt(counter) & ", '" & Datum(counter) & "', '" & link(counter) & "');"
    9. datenbank_insert(test)
    10. Exit Sub
    11. Sub datenbank_insert(ByVal sql)
    12. objConnection.Close()
    13. objDataView = Nothing
    14. objDataSet = New DataSet()
    15. Try
    16. objConnection.Open()
    17. objDataAdapter = New OleDb.OleDbDataAdapter(Sql, objConnection)
    18. objDataAdapter.Fill(objDataSet, "g_grafikkarte")
    19. objDataView = New DataView(objDataSet.Tables("g_grafikkarte"))
    20. objConnection.Close()
    21. Catch ex As Exception
    22. objConnection.Close()
    23. ListBox4.Items.Add(ex.ToString)
    24. End Try
    25. End Sub


    Das Problem sind jetzt die blabla(counter), die mit Random Content gefüllt sind.

    Ich weiß, dass der Code nicht sonderlich sauber ist:D

    *Topic verschoben*

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Ich hab das hier mal ergänzt, aber bei mir funktioniert das ganze mit Oledb leider nicht.
    Vll. sieht jemand wo der Fehler ist:

    VB.NET-Quellcode

    1. Dim objConnection As OleDb.OleDbConnection = New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; " & "Data Source=C:\Datenbank\datenbank.accdb")
    2. Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    3. Try
    4. objConnection.Open()
    5. objConnection.CreateCommandX("INSERT INTO g_grafikkarte (neu, ueberschrift, inhalt, Datum, link) VALUES (false, '?', '?, '?', '?');", _
    6. inhalt1, inhalt2, inhalt3, inhalt4)
    7. objConnection.Close()
    8. Catch ex As Exception
    9. MsgBox(ex.ToString)
    10. End Try
    11. End Sub
    12. '.................. Cut zu Modul
    13. Public Module SqlCeExtensions
    14. ''' <summary>
    15. ''' allgemeine Methode, aus einer SqlCeConnection, einem CommandText und optionalen Werten ein parametrisiertes SqlCeCommand zu erstellen
    16. ''' </summary>
    17. <Runtime.CompilerServices.Extension()> _
    18. Public Function CreateCommandX(ByVal con As OleDb.OleDbConnection, ByVal commandText As String, ByVal ParamArray values As Object()) _
    19. As OleDb.OleDbCommand
    20. Dim splits = commandText.Split("?"c) ' Parameter-Platzhalter '?' identifizieren
    21. If splits.Count <> values.Length + 1 Then Throw New ArgumentException( _
    22. "Anzahl der Argumente passt nicht zur Anzahl der Parameter-Platzhalter im CommandText")
    23. Dim cmd = New OleDb.OleDbCommand()
    24. ' für jeden Platzhalter einen DbParameter adden, und den Param-Namen an den Platzhalter schreiben
    25. For i = 0 To values.Length - 1
    26. Dim param = cmd.Parameters.AddWithValue("@a" & i, values(i))
    27. splits(i) = splits(i) & param.ParameterName
    28. Next
    29. cmd.CommandText = String.Concat(splits)
    30. cmd.Connection = con
    31. Return cmd
    32. End Function
    33. End Module


    Das Modul wurde aus dem Link oben genommen.

    Danke schonmal:)
    ah - jetzt sehe ich glaub den Fehler:
    Du erstellst zwar ein Command, rufst aber nirgends .ExecuteNonQuery() auf.

    dein Code aus post#1 scheint mir noch wirrer: das hat funktioniert, bis auf wenn Sonderzeichen auftraten?

    Ich meine: kann schon sein, dasses funzt. Ich bin noch nie auf die Idee gekommen, einen DataAdapter mit einem InsertCommand-Text zu initialisieren, und dann DataAdapter.Fill aufzurufen.
    Weil .Fill soll ja eine Dataset-Table befüllen, also aus der DB lesen. Lesen geht aber natürlich nicht mit einem InsertCommand-Text, daher weißichnich, was DataAdapter.Fill in solchem Falle macht - vlt. funzt das ja trotzdem.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Genau das ist mir gerade auch aufgefallen - habs jetzt verbessert. Ja der erste Code hat komischerweise funktioniert - das kommt davon wenn man sich unsauberen Code aus dem WWW zusammenkopiert. Langsam steige ich aber dahinter...
    Wenn ich das ganze jetzt so aufrufe...

    VB.NET-Quellcode

    1. objConnection.CreateCommandX("INSERT INTO g_grafikkarte (neu, ueberschrift, inhalt, Datum, link) VALUES (false, '?', '?, '?', '?');", aktuell_satz, aktuell_satz, aktuell_satz, aktuell_satz).ExecuteNonQuery()


    ...kriege ich folgende Exception:

    System.Data.OleDb.OleDbException (0x80040E14): Syntax error (missing operator) in query expression ''@a1, '@a2', '@a3');'.
    bei System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
    bei System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
    bei System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
    bei System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
    bei System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
    bei System.Data.OleDb.OleDbCommand.ExecuteNonQuery()
    bei feedpost.Form1.Button2_Click(Object sender, EventArgs e) in C:\Users\Johannes J\Documents\Visual Studio 2010\Projects\feedpost\feedpost\Form1.vb:Zeile 307.


    Zeile 307 ist der obige Aufruf...
    ah ja. Da muss die Syntax angepasst werden - Access kennt das nicht mit benannten Parametern im Commandtext.
    probierma:

    VB.NET-Quellcode

    1. <Runtime.CompilerServices.Extension()> _
    2. Public Function CreateCommandX(ByVal con As OleDb.OleDbConnection, ByVal commandText As String, ByVal ParamArray values As Object()) _
    3. As OleDb.OleDbCommand
    4. Dim splits = commandText.Split("?"c) ' Parameter-Platzhalter '?' identifizieren
    5. If splits.Count <> values.Length + 1 Then Throw New ArgumentException( _
    6. "Anzahl der Argumente passt nicht zur Anzahl der Parameter-Platzhalter im CommandText")
    7. Dim cmd = New OleDb.OleDbCommand()
    8. ' für jeden Platzhalter einen DbParameter adden, und den Param-Namen an den Platzhalter schreiben
    9. For i = 0 To values.Length - 1
    10. Dim param = cmd.Parameters.AddWithValue("@a" & i, values(i))
    11. Next
    12. cmd.CommandText = commandText
    13. cmd.Connection = con
    14. Return cmd
    15. End Function
    wenn das klappt kannmans noch weiter vereinfachen
    Da kriege ich leider folgende Exception:

    System.Data.OleDb.OleDbException (0x80040E14): Syntax error (missing operator) in query expression ''?, '?', '?');'.
    bei System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
    bei System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
    bei System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
    bei System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
    bei System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
    bei System.Data.OleDb.OleDbCommand.ExecuteNonQuery()
    bei feedpost.Form1.Button2_Click(Object sender, EventArgs e) in C:\Users\Johannes J\Documents\Visual Studio 2010\Projects\feedpost\feedpost\Form1.vb:Zeile 308.
    schade - schicker hätte ich gefunden, wenn die DB-Provider sich da mehr hätten einigen können. Also wo man eh eine Extrawurst für OleDb schreiben muß, dann kann man die auch so einfach wie möglich halten:

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' allgemeine Methode, aus einer OleDbConnection, einem CommandText und optionalen Werten ein parametrisiertes OleDbCommand zu erstellen
    3. ''' </summary>
    4. ''' <remarks>Vorrausgeetzt ist, dass die übergebenen values Datentypen haben, die zu den in der Datenbank
    5. ''' festgelegten Spalten passen. Eine Überprüfung findet nicht statt.</remarks>
    6. <Runtime.CompilerServices.Extension()> _
    7. Public Function CreateCommandX(ByVal con As OleDb.OleDbConnection, ByVal commandText As String, ByVal ParamArray values As Object()) _
    8. As OleDb.OleDbCommand
    9. If commandText.Split("?"c).Count <> values.Length + 1 Then Throw New ArgumentException( _
    10. "Anzahl der Argumente passt nicht zur Anzahl der Parameter-Platzhalter im CommandText")
    11. CreateCommandX = New OleDb.OleDbCommand() With {.CommandText = commandText, .Connection = con}
    12. For i = 0 To values.Length - 1
    13. CreateCommandX.Parameters.AddWithValue("@a" & i, values(i))
    14. Next
    15. End Function