DBExtension Dataset.Table.Fill(conditions) anfälligkeiten für SQL Injection vorhanden?

  • VB.NET

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

    DBExtension Dataset.Table.Fill(conditions) anfälligkeiten für SQL Injection vorhanden?

    Moin Com,
    ich nutze die DBEx von EDR und habe nun in einem Form ein Textfeld mit dessen Hilfe der Anwender die zu ladenden Rows einschränken können soll. Also im Grunde nix anderes als ne dynamische Where-Clause, welche ich dann eben an die .Fill Methode hänge.

    Dataset.Table.Fill(Where-Clause)

    Nu frag ich mich, wie hier die Gefahr einer SQL-Injection aussieht. Ich gehe hier nicht von Böswilligkeit, sondern von Unwissenheit auf seiten der Anwender aus, nichts des zu trots sollte ich es bedenken. Ich ging bisher davon aus, dass wenn ich ein Feld eines typ.Dataset anspreche, dieses ja das handling der Eingaben der User übernimmt und dementsprechend die Werte schon 'sichern' sollte. Wie sieht es aber mit einer von meinem Code erstellten Where-Clause aus? Muss ich da was machen? Kann ich da was machen?

    Eine Parametrisierte Query iat ja nicht wirklich möglich, da ja die eigendliche Query erst von der DBEx erzeugt wird.

    Ich hab schon versucht hier im Forum was dazu zu finden, aber bis auf einen etwas vagen Threadt, hab ich nix gefunden.

    DianonForce schrieb:

    Eine Parametrisierte Query iat ja nicht wirklich möglich, da ja die eigendliche Query erst von der DBEx erzeugt wird.
    dochdoch, da ist eine parametrisierte Query vorgesehen.
    Du gibst die Methode falsch wieder, die lautet iwie

    VB.NET-Quellcode

    1. .Fill(whereClause As String, paramarray values as Object())
    wenn ich mich recht erinnere.
    in der whereClause gilt dann ? als parameterplatzhalter, und die parameter werden automatisch erstellt anhand der Datentypen der values.
    Ok, hab ich mich zu früh gefreut.

    Wenn ich eine Bedingung wie diese habe

    WHERE (artnr1 LIKE '%?%' OR artnr2 LIKE '%?%') AND (artnr1 LIKE '%?%' OR artnr2 LIKE '%?%')

    also in den Spalten artnr1 oder artnr2 nach z.B. Drucker und HP suchen will.

    muss ich dann die beiden Parameter wirklich doppeln? Oder kann ich wie bei String.Format ne art Zuweisung der Parameter auf mehrere Stellen in der Bedinung erreichen?

    Sorry wenn das vielleicht ne doofe Frage ist, aber bei MySQl könnt ich das mit @Parameter einen Parameter mehrfach zuweisen, aber wenn ich das richtig verstehe geht das wohl hier nicht.

    DianonForce schrieb:

    aber bei MySQl könnt ich das mit @Parameter einen Parameter mehrfach zuweisen, aber wenn ich das richtig verstehe geht das wohl hier nicht.
    Jo, haste recht verstanden: denselben Wert auf mehrere Platzhalter-Positionen zu beziehen habich nicht vorgesehen.
    Ich habs halt implementiert, wie*s "bei Access" ist - nicht wie "bei MySql".
    Sorry, muss nochmal nerfen, warscheinlich bin ich nur zu doof

    ich bekomm die Fehlermeldung
    conditions contains more placeholders than paramValues are passed


    Ich erstelle mir mit folgender Funktion meinen SQL String und die Parameter, aber irgendwie übersehe ich wohl was.

    tbNameSuche enthält folgenden String "Konica C558"

    VB.NET-Quellcode

    1. Dim geraetSuchString As String = "artstamm LEFT JOIN modell ON artstamm.artnr = modell.modnr LEFT JOIN artlief ON artstamm.artnr = artlief.artnr " &
    2. "WHERE artlief.artliefnr = 1 {0}"
    3. Dim geraetSuchStringWordsExt As String = "AND (arttext1 LIKE '%?%' OR arttext2 LIKE '%?%' OR artnr1 LIKE '%?%')"
    4. Dim geraetSuchStringExt As String = ""
    5. Dim words As String() = tbNameSuche.Text.Split(New Char() {" "c})
    6. Dim params As New List(Of String)
    7. For Each word As String In words
    8. geraetSuchStringExt &= geraetSuchStringWordsExt
    9. For i As Integer = 0 To 2
    10. params.Add(word)
    11. Next
    12. Next
    13. Dim condition As String = String.Format(geraetSuchString, geraetSuchStringExt)
    14. If cbMaschinenArtikel.Checked Then
    15. condition &= " AND arttyp = 1"
    16. End If
    17. If cbAktiv.Checked Then
    18. condition &= " AND modaktiv = True"
    19. End If
    20. Debug.Print(condition)
    21. dsCommerz.artstamm.Fill(condition, params)


    rauskommen tut dabei folgender Teil der Query

    SQL-Abfrage

    1. "artstamm
    2. LEFT JOIN
    3. modell ON artstamm.artnr = modell.modnr
    4. LEFT JOIN
    5. artlief ON artstamm.artnr = artlief.artnr
    6. WHERE
    7. artlief.artliefnr = 1
    8. AND
    9. (arttext1 LIKE '%?%' OR arttext2 LIKE '%?%' OR artnr1 LIKE '%?%')
    10. AND
    11. (arttext1 LIKE '%?%' OR arttext2 LIKE '%?%' OR artnr1 LIKE '%?%')
    12. AND
    13. arttyp = 1 AND modaktiv = True"


    Was mach ich falsch? in Params sind 6 Werte
    sagt dir doch die Exception: Dein Sql-String enthält mehr ParameterPlatzhalter als du an Parameter-Werten übergibst.
    Derzeit sehe ich da 4 ? in Snippet#2 - wieviele Parameter-Werte du übergibst kann ich ja nicht sehen.
    Doch kannich doch so leidlich: je geraetSuchStringWordsExt übergibst du 3 params.

    Hmm - das wären dann zuviele Parameter - naja - klär das mal, obs damit was zu tun haben kann.
    Vlt habich die Exception falsch formuliert, und sie wird nicht nur bei zuwenig Params geworfen, sondern auch bei zuvielen (meldet dann aber: "zuwenig").
    Öh, ich zähle da 6 ?

    Quellcode

    1. AND
    2. (arttext1 LIKE '%?%' OR arttext2 LIKE '%?%' OR artnr1 LIKE '%?%')
    3. AND
    4. (arttext1 LIKE '%?%' OR arttext2 LIKE '%?%' OR artnr1 LIKE '%?%')


    Wie gesagt params enthält 6 Werte, habe ich auch überprüft, wenn ich den Code bei dsCommerz.artstamm.Fill(condition, params)] anhalte, sagt mir visualstudio das params eine lenght von 6 hätte.



    Dies sollte auch so sein, da ich die Eingebe des Anwenders
    Konica C558
    splitte. Danach hab ich ein Array mit 2 Werten. Dies arbeite ich mit einer For Each ab und gennerier pro Wert 3 Einträge im List Element.
    Also rein von meinem Verständnis und Visual Studio hab ich zum Zeitpunkt des Aufrufs von .Fill ein Objekt mit 6 Werten.

    Was mich wundert an der Stelle wo es die Excepten wirft, sieht das ganze so aus.



    Vielleicht gehört das auch so, dazu verstehe ich zu wenig von dem was da passiert. Aber was anderes fällt mir hald auch ned auf.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DianonForce“ ()

    mist - du hast recht.
    Jo, das ist gravierend.
    Weil Anzahl von Werten und Platzhaltern scheint ja übereinzustimmen - da weiss ich nu auch nicht, warum er meldet, dass dem nicht so wäre.

    Musste vlt. mal im Einzelschritt reingehen und debuggen, wieso er da zu diesem falschen Ergebnis kommt.

    Übrigens hatte ich das so in Erinnerung, dass man bei parametrisierten Sql-Abfragen die Single-Quotes weglässt.
    Ok, ich habs raus. Mein Problem ist/war, das ich an .Fill(whereClause As String, paramarray values as Object())( ein List-Objekt übergebe.
    Ich hab noch nen bissel gegoogelt, wenn ich das richtig verstehe, packt paramarray alles was kein Array ist in ein Array. Da .Fill aber nur die erste Dimension durchläuft gibt es da natürlich nur 1 Objekt und die Meldung ist föllig verständlich.
    Übergeb ich mein List(of Strings) Objekt aber mit .ToArray() klapts.

    Also statt

    VB.NET-Quellcode

    1. dsCommerz.artstamm.Fill(condition, params)

    so

    VB.NET-Quellcode

    1. dsCommerz.artstamm.Fill(condition, params.ToArray())


    ErfinderDesRades schrieb:


    Übrigens hatte ich das so in Erinnerung, dass man bei parametrisierten Sql-Abfragen die Single-Quotes weglässt.

    ok, damit hast du recht, muß ich mir die Wildcardas vorher in die Parameter basteln

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DianonForce“ ()

    DianonForce schrieb:

    ok, damit hast du recht, muß ich mir die Wildcardas vorher in die Parameter basteln
    Sollte man zunächstmal denken. Wenn ich mich aber recht erinnere bruchste das nicht.
    Jdfs. Irgendwo hab ich einigen Aufwand getrieben, WildCards in Parameter-Werte reinzumogeln.
    Damits so geht:

    SQL-Abfrage

    1. (arttext1 LIKE %?% OR arttext2 LIKE %?% OR artnr1 LIKE %?%)
    Wobei artnr1 LIKE %?% äusserst verdächtig ist - einen Nummer sollte normalerweise kein String sein, und von daher auch nicht mit LIKE auswertbar.