2016-11-01 4 views
-3

私はDBからログインするフォームを作った。コードは自明でなければなりません。MYSQL注射からの良い予防?

private void button1_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     string MyConnection = "datasource=localhost;port=3306;username=root;password=xdmemes123"; 
     MySqlConnection myConn = new MySqlConnection(MyConnection); 
     MySqlCommand SelectCommand = new MySqlCommand("select * from life.players where DBname='" + this.username.Text + "' and DBpass='" + this.password.Text +"' ; ", myConn); 
     MySqlDataReader myReader; 
     myConn.Open(); 
     myReader = SelectCommand.ExecuteReader(); 
     int count = 0; 
     while (myReader.Read()) 
     { 
      count = count + 1; 
     } 
     if (count == 1) 
     { 
      Properties.Settings.Default.Security = "Secure"; 
      Properties.Settings.Default.AdminName = username.Text; 
      Properties.Settings.Default.AdminPass = password.Text; 
      Properties.Settings.Default.Save(); 
      MessageBox.Show("Logged in"); 
      this.Hide(); 
      Form2 f2 = new Form2(); 
      f2.ShowDialog(); 
     } 
     else if (count > 1) 
     { 
      Properties.Settings.Default.Security = "Insecure"; 
      MessageBox.Show("Incorrect!"); 
     } 
     else 
     { 
      Properties.Settings.Default.Security = "Insecure"; 
      MessageBox.Show("Incorrect!"); 
      myConn.Close(); 
     } 
} 
    catch (Exception ex) 
    { 
     MessageBox.Show("Something went wrong. Error copied to clipboard."); 
     Clipboard.SetText(ex.Message); 
    } 
} 

しかし、私の質問は、これがMYSQL注入から安全かどうかです。もしそうでなければ、私はそれを安全にするために何ができますか?

可能であれば、このコードを書く方法を書いてください。私はこのコーディングには全く新しいですが、本当にそれを愛し、私のプログラムを進めたいと思います。インラインテキストは、注入が発生することを可能にするようあなたが使用することができます

+3

ありません、これはSQLインジェクションから安全ではありません:それは使用SELECT *、唯一SELECT count(*)ないことに注意してください。読んでみると、すぐにその理由がわかります。 – DavidG

+1

これは、SQLインジェクションの脆弱性がどのように実装されているかを正確に示しています。 – pid

+0

'this.username.Text ==" 0 "; SomeTablesからの削除 - " –

答えて

1

コードは、実際に、それは完璧な例ですが、SQLインジェクションの脆弱性である - 文字列の連結とSELECT *は、入力などへの攻撃を許すx' OR 1=1;#のパスワードとすべてユーザ名と暗号化されていないパスワードを取得します。結果をカウントするための不必要なループでさえ、彼が成功したことを伝える顕著な遅延を引き起こします。

次のコードは、NOTのパスワードを認証する適切な方法ですが、注入には脆弱ではありません。デモンストレーションの目的のみです。

//Reuse the same command with different connections 
void InitializePlayerCmd() 
{ 
    var query = "SELECT COUNT(*) FROM life.players where [email protected] and [email protected]"; 
    var myCmd= new MySqlCommand(query); 
    myCmd.Parameters.Add("@name", SqlDbType.VarChar,30); 
    myCmd.Parameters.Add("@pass", SqlDbType.VarChar,200); 
    _playerCheckCmd=myCmd; 
} 

//..... 
int CheckPlayer(string someUserName, string someAlreadyHashedString) 
{ 
    var connectionString=Properties.Settings.Default.MyConnectionString; 
    using(var myConn= new MySqlConnection(connectionString)) 
    { 
     _playerCheckCmd.Connection=myConn; 
     _playerCheckCmd.Parameters["@name"].Value=someUserName; 
     _playerCheckCmd.Parameters["@pass"].Value=someAlreadyHashedString; 
     myConn.Open(); 
     var result=_playerCheckCmd.ExecuteScalar(); 
     return result; 
    } 
} 
3

Parameters.Addは、より良いSQLの例は次のとおりです。インジェクションの問題に加えて

using (var conn = new SqlConnection(@"datasource=localhost;port=3306;username=root;password=xdmemes123")) 
{ 
    conn.Open(); 
    var command = new SqlCommand("", conn); 
    command.CommandText = "select * from life.players where DBname='@sqlName' and DBpass='@sqlPass"; 
    command.Parameters.Add("@sqlName", SqlDbType.VarChar).Value = this.username.Text;   
    command.Parameters.Add("@sqlPass", SqlDbType.VarChar).Value = this.password.Text; 
    using (SqlDataReader myReader = command.ExecuteReader()) 
    { 
     while (myReader.Read()) 
     { 
      string value = myReader["COLUMN NAME"].ToString(); 
     } 
    }  
} 

、あなたのパスワードのいずれかをハッシュしていない、私が探してお勧めしますそれに。

+1

いいえ、いいえ、できません! ['AddWithValue'を使わないでください。](http://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/) – DavidG

+0

私はこれがはい? Addだけを使用して、あなたは言う? – FakeCaleb

+0

リンクを読んで、私はそれが言っていることを繰り返し述べません。 – DavidG