Dickes Problem mit CRecordset daten in Datenbank schreiben!



  • *rofl* woher der Fehler kommt weis ich jetz nicht, aber das m_beschreibung soll doch sicher nicht als Text in die Datenbank oder^^ Den String solltest du dir vorher entsprechend zusammen basteln., Weil so würde der Insert den String "m_breschreibung" abschicken und nicht den Inhalt der Variable, die du sicher heir meinst



  • CString Statment;
    Statment = "INSERT INTO Artikel (Beschreibung) VALUES ("+m_beschreibungh+")";
    	db.ExecuteSQL(Statment);
    

    So?



  • wenn m_beschreibung ein CString ist, dann ja



  • ok Fehlermeldung bleibt aber immer noch 😞



  • ...weil das ein String ist und die Apostroph fehlen:

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

    Und willst du wirklich nur ein Feld neu in die Datenbank schreiben oder bei einem bestehenden Datensatz das Feld Beschreibung ändern/füllen ? Dann brauchst du ein UPDATE.
    Da ist übrigens ein h zu viel bei m_beschreibungh...



  • das h ist da richtig 🙂

    und ich will auch mehrere Sachen eintragen, bez. einen ganz neuen Datansatz eintragen 🙂

    Aber jetzt geht es!



  • 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 ...


Anmelden zum Antworten