Dickes Problem mit CRecordset daten in Datenbank schreiben!



  • ich denk mal das (Beschreibung) hat da nix verloren

    wenn deine Tabelle aus z.b. 3 Feldern besteht musst du (glaub ich)auch 3 Felder übergeben

    also:

    Statment = "INSERT INTO Artikel VALUES ('"+m_beschreibungh+"','','')";
    

    Jedenfalls mach ichs atm so und es tut wunderbar



  • Habt Ihr eigentlich noch nie was von SQL-Injection gehört?
    Jeder der mit SQL zu tun hat sollte sich eine Regel angewöhnen:
    Nie einen Parameter in den SQL-String einbetten!!!

    Bitte macht das über ein "?" im SQL-String und fügt den Parameter dem Abfrageobjet an.
    Fazit:

    Statment = "INSERT INTO Artikel VALUES (?,'','')";
    


  • Jochen Kalmbach schrieb:

    Habt Ihr eigentlich noch nie was von SQL-Injection gehört?
    Jeder der mit SQL zu tun hat sollte sich eine Regel angewöhnen:
    Nie einen Parameter in den SQL-String einbetten!!!

    Bitte macht das über ein "?" im SQL-String und fügt den Parameter dem Abfrageobjet an.
    Fazit:

    Statment = "INSERT INTO Artikel VALUES (?,'','')";
    

    Im Prinzip schon, nur krieg ich bei mir ums verrecken kein SQL Injection hin 🙄

    Aber hast recht auf SQL Injection sollte man generell achten



  • Jochen Kalmbach schrieb:

    Habt Ihr eigentlich noch nie was von SQL-Injection gehört?
    Jeder der mit SQL zu tun hat sollte sich eine Regel angewöhnen:
    Nie einen Parameter in den SQL-String einbetten!!!

    Bitte macht das über ein "?" im SQL-String und fügt den Parameter dem Abfrageobjet an.
    Fazit:

    Statment = "INSERT INTO Artikel VALUES (?,'','')";
    

    ??? wie mienst du das jetzt ???

    Ich mache mir meine Statements gern als Konstante udn bastel mir dann bei Bedarf das Statement zusammen. Das schick ich dann ab.



  • Jochen Kalmbach schrieb:

    Statment = "INSERT INTO Artikel VALUES (?,'','')";
    

    Genau sowas hat mir kürzlich das Projekt zerkloppt (beim Wechsel von NT zu XP war das, glaube ich), allerdings war das Fragezeichen in m_strFilter, was dann nicht mehr funktioniert hat. -> rund 400 Änderungen. Seit dem mag ich keine Fragezeichen als Platzhalter mehr 🙂



  • Pellaeon schrieb:

    Jochen Kalmbach schrieb:

    Habt Ihr eigentlich noch nie was von SQL-Injection gehört?

    ??? wie mienst du das jetzt ???

    Simples Beispiel:

    sprintf(sqlStatement, "SELECT fieldlist FROM table WHERE field = '%s'", name);
    

    Wenn das "name" nun durch jemanden externen Eingebenen werden kann (z.B. Als Eingabefeld), dann würde ein normaler Benutzer folgendes Eingeben:

    Mein Name

    Ein anderer Benutzer würde folgendes eingeben:

    x'; DROP TABLE table; --

    Fazit: Deine Tabelle ist weg.



  • Hallo? es geht doch so wie es oben steht 🙂 Wieso dann noch die große Diskusion Beschreibung ist einfach nur ein Feld in meiner Access Tabelle.



  • und was bringt da das "?" ?



  • @Jens Bond: Es bezweifelt ja niemand, dass es nicht geht... es geht nur darum, dass Du Code verwendest, der sehr gefährlich ist und Du Dir dessen nicht bewusst bist. (Unterstellung:) Für Deine simple/kleine Anwendung mag das ja alles ok sein..

    @Pellaeon: Das bringt dass jemand Fremdes Deine Datenbank nicht kaputt machen kann...
    Den vom Benutzer eingegebenen String übergibst Du nicht direkt im SQL-Statement sondern in einem speziellen Parameter-Objekt der Abfrage. Somit kann er Dein SQL-Statement nicht mehr verändern und er würde tatsächlich nach diesem komischen String suchen und nicht die Tabelle löschen 😉
    http://msdn.microsoft.com/library/en-us/vccore/html/_core_recordset.3a_.parameterizing_a_recordset_.28.odbc.29.asp



  • den Name müsste ich doch eh in Apostrophe schreiben, also was soll da passiern? Dann wird das ;DROP TABLE doch auch mit als String bewertet
    INSERT ... name = 'jochen;DROP TABLE Personsn';

    edit: ah stimmt bei Zahlen, die man vorher nicht selbset kontrolliert gibts Probleme



  • Vermutlich hast Du den String nicht gaaaanz aufmerksam gelesen:

    x'; DROP TABLE table; --

    =>
    SELECT fieldlist FROM table WHERE field = 'x'; DROP TABLE table; --'

    Das sind dann drei separate SQL-Befehle:

    SELECT fieldlist FROM table WHERE field = 'x';
    DROP TABLE table;
    --'



  • HM ok ohne gute vorherige Prüfung geht das schief.
    Aber mit den ? das habe ich trotzdem noch nie gesehen. Kannst nicht mal ein kurzes prägnantes Bsp posten, anstatt nur Brocken hinzuschmeißen? 😉 🙂



  • Da ich C++ und Datenbanke hasse, hier ein Beispiel in C# (kannste aber auch in MC++ / C++/CLI machen; und wenn Du Dir mühe gibst geht das auch mit C++):

    Gut:

    using System;
    using System.Data.OleDb;
    namespace MyApp
    {
      class MyClass
      {
        static void Main(string[] args)
        {
          string derParameterVomBenutzer = "x'; DROP TABLE table; --'";
          using(OleDbConnection con = new OleDbConnection())
          {
            con.ConnectionString = "File Name = DieDatenbank.udl";
            using(OleDbCommand cmd = new OleDbCommand("SELECT fieldlist FROM table WHERE field = ?", con))
            {
              cmd.Parameters.Add(new OleDbParameter("0", derParameterVomBenutzer));
              using(OleDbDataReader reader = cmd.ExecuteReader())
              {
                while (reader.Read())
                {
                  // verarbeite die Zeilen...
                }
              }
            }
          }
        }
      }
    }
    

    Schlecht:

    using System;
    using System.Data.OleDb;
    namespace MyApp
    {
      class MyClass
      {
        static void Main(string[] args)
        {
          string derParameterVomBenutzer = "x'; DROP TABLE table; --'";
          using(OleDbConnection con = new OleDbConnection())
          {
            con.ConnectionString = "File Name = DieDatenbank.udl";
            using(OleDbCommand cmd = new OleDbCommand(string.Format("SELECT fieldlist FROM table WHERE field = '{0}'", derParameterVomBenutzer), con))
            {
              using(OleDbDataReader reader = cmd.ExecuteReader())
              {
                while (reader.Read())
                {
                  // verarbeite die Zeilen...
                }
              }
            }
          }
        }
      }
    }
    


  • ich glaube da würd ich lieber mit Remove vom CString auf Teufel komm raus einfach alle ' aus dem Nutzerstring entfernen lassen und dann hat sich das Problem auch gelöst 😃
    ExecuteSQL akzeptiert ja auch nur 1 Parameter ...



  • Im managed-Code ist es wie gesagt nur eine Zeile mehr, deshalb gibt es keinen Grund es da nicht zu machen. Wie das ganze in native C++ aussieht sei mal dahingestellt. Rein Format muss man es natürlich auch machen... ich arbeite mit den ATL-DB-Consumer-Templates und da geht es eigentlich auch ohne Probleme...



  • Hm in C++ wüsst ich jetzt auch nicht auf anhieb, wie man das so macht.
    Ich würde halt entweder die Zeichen entfernen, oder: wie kann man in nem SQl-String sagen, dass das ' entwertet werden soll? so wie in C++ mit dem \".
    Geht das in SQL genauso? Hatte das Problem bisher noch nicht. Aber alternativ kann man auch alle ' suchen und halt dafür sorgen, dass die "entwertet" werden, wenn man denn weis wie das geht^^ und dann kann man es wieder einfach in den SQL-Comment einsetzen und sicher sein, dass da nichts reingekogelt wird.



  • Fakt: Die einzige sichere Lösung ist die Verwendung von Parametern.



  • Jochen Kalmbach schrieb:

    Fakt: Die einzige sichere Lösung ist die Verwendung von Parametern.

    Nöö, die Parametervariante muss das ja auch irgendwie auf einen String zurück führen nicht? Es wird einem da halt nur die Arbeit abgenommen.



  • Nein, tut sie nicht. Die Parameter werden separat übertragen und somit ist hier niergends ein String mehr im Spiel.
    Fazit2: Die einzige sichere Lösung ist die Verwendung von Parametern.



  • So nun werde ich diesen Thread mal wieer aus kramen. Also

    Statment = "INSERT INTO Artikel (Beschreibung) VALUES ('"+m_beschreibungh+"')";
    

    DAs ging ja gnz gut nun habe ich das Problem das ich mehrere sachen eintragen will. Habe das dann mal in etwas so Probiert:

    Statment = "INSERT INTO Artikel (Beschreibung,Preis) VALUES ('"+m_beschreibungh+","+m_preish+"')";
    

    prob ist dabei wieder hinten die Formatierung. Weil wenn ich vorne Preis weg lasse packt er mir alles in ein Feld.

    Vielleicht kann mir da ja noch mal einer helfe is sicher nicht viel arbeit für jemanden der so was öfters macht 🙂

    THX


Anmelden zum Antworten