Announcement

Collapse
No announcement yet.

C# Injections

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • C# Injections

    Hey,

    ich bin grade dabei mein Programm gegen SQL-Injections aber eins verstehe ich nicht:
    Was ist der Unterschied zwischen Add und AddwithValue und was sollte man am besten verwenden?

    Zudem noch eine konkrete Frage:

    Code:
    MySqlConnection sql_con = new MySqlConnection();
    MySqlCommand sql_command_s= new MySqlCommand();
    MySqlCommand sql_command_l = new MySqlCommand();
    
    string l_id, o_id;
    
    o_id = "select * from Eintrag where Eintrag_ID = '" +
                                id + "';";
    
    l_id = "delete from Eintrag where Eintrag_ID = '" + textBox_ID.Text + "';";
    
    sql_con.ConnectionString = Anmeldung();
    
    sql_command_s.CommandText = o_id;
    sql_command_l.CommandText = l_id;[
    
    sql_command_l.Connection = sql_con;
    sql_command_l.ExecuteNonQuery();
    Naja, nun man hängt doch dann einfach die Parameter mit Add an den Commandtext an und danach macht man, wie bei mir:

    Code:
    sql_command_l.CommandText = loeschen_id;
    sql_command_s.Parameters.Add("@id", textBox_ID.Text);
    Muss ich das an den String anhängen oder an den commandtext?
    Zuletzt editiert von Threin; 31.01.2014, 10:56.

  • #2
    Bei Add musst du den Typ und den Wert angeben. Bei AddWithValue brauchst du nur den Wert und der Typ wird erraten. Je nach Datenbank (besser je nach nach Implementierung der entsprechenden Command Klasse) kann da aber auch schon mal falsch geraten werden und zu Problemen führen. Wie gut sich der MySQL Provider da verhält weiß ich nicht. Der Aufruf per Add ist aber auch nicht wirklich aufwändiger.

    Muss ich das an den String anhängen oder an den commandtext?
    Häh? Die Parameter gehören zum MySqlCommand da wird nix angehängt. Der CommandText mit den Parameterplatzhaltern und die Parameterwerte werden an den Datenbankserver gesendet. Dort wird nur anhand des CommandTextes ausgetüftelt wie das SQL auszuführen ist und dann erst werden die Parameterwerte hinzugemischt. Da finden nie irgendwelche Textersetzungen, Anhängungen oder ähnliches statt. Darum ist es ja sicher.

    Edit : Ok sehe gerade deinen Add Aufruf das sollte man nicht so machen. Ich kenne den konkreten MySQL Provider zwar nicht aber da sollte man vermutlich auch nicht so vorgehen. Diese Add Überladung kann man mal mit dem Typ und mal mit einem Wert aufrufen. Nach irgendeinem undurchsichtigen Verfahren wird dann gewürfelt was gemeint war. Da diese Idee von Microsoft sagenb wir mal suboptimal ist ist diese Überladungen auch als obsolet (heißt die soll man nicht mehr verwenden) markiert.

    Beispiele aus der Doku wie man Add mit Typ aufruft
    Zuletzt editiert von Ralf Jansen; 31.01.2014, 00:05.

    Comment


    • #3
      Ja, ich meinte auch nicht anhängen aber naja, zudem wollte ich das auch eigentlich direkt mit dem Typen machen, weil man ja sonst genau so gut Addwithvalue nehmen könnte.
      Also müsste das ganze dann so aussehen?

      Code:
      MySqlConnection sql_con = new MySqlConnection();
      MySqlCommand sql_command_s= new MySqlCommand();
      MySqlCommand sql_command_l = new MySqlCommand();
      
      string l_id, o_id;
      
      o_id = "select * from Eintrag where Eintrag_ID = '" +
                                  id + "';";
      
      l_id = "delete from Eintrag where Eintrag_ID = '" + ?id + "';";
      
      sql_con.ConnectionString = Anmeldung();
      
      sql_command_s.CommandText = o_id;
      
      sql_command_l.CommandText = l_id;
      sql_command_l.Prepare();
      sql_command_l.Parameters.Add("id", MySqlDbType.Int32, 11).Value = textBox_ID.Text);
      
      sql_command_l.Connection = sql_con;
      sql_command_l.ExecuteNonQuery();
      So ist das doch richtig oder?

      oder muss ich dann die Value so zuweisen:
      sql_command_l.Parameters["@id"].Value = textBox_ID.Text;
      Zuletzt editiert von Threin; 31.01.2014, 12:02.

      Comment


      • #4
        Nö die Add Methode liefert dir ja das erstellte Parameter Objekt zurück da kannst du auch wie in deinem Code gezeigt direkt den Value zuweisen. Der Aufruf von Prepare ist aber überflüssig und dein SQL sieht noch ein wenig merkwürdig aus.

        Es sollte eigentlich eher so aussehen
        Code:
        "delete from Eintrag where Eintrag_ID = @id";
        Wobei ich nicht weiß ob der Platzhalter @ oder ? sein soll die mysql Doku scheint einfach beides zu benutzten je nachdem wo man guckt. Aber wenn benutz das gleiche Zeichen im SQL und in den Parameteren.

        Comment


        • #5
          Also dann so:

          Code:
          MySqlConnection sql_con = new MySqlConnection();
          MySqlCommand sql_command_s= new MySqlCommand();
          MySqlCommand sql_command_l = new MySqlCommand();
          
          string l_id;
          
          l_id = "delete from Eintrag where Eintrag_ID = '" + ?id + "';";
          
          sql_con.ConnectionString = Anmeldung();
          
          sql_command_l.CommandText = l_id;
          sql_command_l.Parameters["id"].Value = textBox_ID.Text; 
          
          sql_command_l.Connection = sql_con;
          sql_command_l.ExecuteNonQuery();
          Fehlt da dann nicht noch vor hiner Parameters .Add oder ist das dann so richtig?
          Ich dachte die Add Methode wäre sicherer und man müsste da so den Typ angegeben und das dass dann so richtig wäre:

          Code:
          sql_command_l.CommandText = l_id;
          sql_command_l.Parameters.Add("id", MySqlDbType.Int32, 11).Value = textBox_ID.Text);
          So wie ich das auch verstanden habe, ist das bei MySQL mit dem Zugriff oben so:
          Code:
          "delete from Eintrag where Eintrag_ID = ?id";
          Das Fragezeichen (oder das @) muss man aber hier nicht mit angeben.
          Code:
          sql_command_l.Parameters["id"].Value = textBox_ID.Text;
          So habe ich das jedenfalls verstanden.

          Comment


          • #6
            Also bei jedem Provider den ich kenne gehört da ein Zeichen hin. Ich bezweifle das MySQL da eine Ausnahme macht.
            In Code sollte das so aussehen.

            [HIGHLIGHT=C#]using(MySqlConnection sql_con = new MySqlConnection(Anmeldung())
            {
            sql_con.Open();
            using(MySqlCommand sql_command_l = sql_con.CreateCommand())
            {
            sql_command_l.CommandText = "delete from Eintrag where Eintrag_ID = ?id";
            sql_command_l.Parameters.Add("?id", MySqlDbType.Int32).Value = Convert.ToInt32(textBox_ID.Text);
            sql_command_l.ExecuteNonQuery();
            }
            }
            [/HIGHLIGHT]

            Comment


            • #7
              Originally posted by Ralf Jansen View Post
              Also bei jedem Provider den ich kenne gehört da ein Zeichen hin. Ich bezweifle das MySQL da eine Ausnahme macht.
              In Code sollte das so aussehen.

              [HIGHLIGHT=C#]using(MySqlConnection sql_con = new MySqlConnection(Anmeldung())
              {
              sql_con.Open();
              using(MySqlCommand sql_command_l = sql_con.CreateCommand())
              {
              sql_command_l.CommandText = "delete from Eintrag where Eintrag_ID = ?id";
              sql_command_l.Parameters.Add("?id", MySqlDbType.Int32).Value = Convert.ToInt32(textBox_ID.Text);
              sql_command_l.ExecuteNonQuery();
              }
              }
              [/HIGHLIGHT]
              Okay, du hattest Recht. Ich habe grad noch einmal geguckt und da war es so, wie man es nicht machen sollte. *hust*
              Was sollte man denn jetzt lieber nehmen, Paramters.Add oder AddwithValue?

              Bei AddWithValue würde das ja so aussehen und der Provider entscheidet dann, wie die Felder gesetzt werden.
              sql_command.Parameters.AddWithValue("?id", textBox_ID.Text);

              oder irre ich mich da?

              Danke noch einmal und das wäre es dann auch zu dem Thema.

              Comment


              • #8
                oder irre ich mich da?
                Ausprobieren.
                Mir gefällt es so wie du es zeigst nicht. TextBox.Text ist ein string die Eintrag_ID aber bestimmt eine Zahl. Also zumindest die Umwandlung in den richtigen Zahl Typ solltest du vornehmen egal ob Add oder AddWithValue.
                Wie der Typ von AddWithValue erraten wird weiß ich nicht ich bezweifle das das auch irgendwo genau beschrieben ist(außer du guckst dir das im Sourcecode an). So wie du es machst hoffst du das bevor die Anfrage an MySQL gesendet wird erstmal die Metadaten von der Datenbank geholt werden. Der Command dadurch merkt das Eintrag_ID ein Int32 ist. Der von dir übergeben Wert ist aber ein string. Der Command müßte also dann selbst noch eine Konvertierung string nach int32 machen. Möglich das das passiert aber du kannst es halt nicht genau überprüfen. Ich vermute eher das er einfach sieht Wert ist ein string dann sende ich mal ?id als string an den Server. Auf dem Server ist aber ein Ausführungsplan für eine Zahl erstellt worden. Entweder wird der verworfen und neu generiert oder du bekommst ne Fehlermeldung. Beides nicht schön. Also lieber gleich selbst machen so wie von mir gezeigt dann bist du nicht von unkontrollierbarer Magie abhängig.

                Comment

                Working...
                X