2

SQL インジェクションを防止しようとしています: 1=1 などのように。

コードは次のとおりです。接続文字列はそこにあります。この質問のために削除しました。

   public void btnSubmit_Click(object sender, EventArgs e)
    {

        String login = txtUser.Text;
        String pass = txtPass.Text;

            string connString = "";
            SqlConnection conn = new SqlConnection(connString);
            conn.Open();



            SqlCommand cmd = new SqlCommand("Select Users,Pass from logintable where Users='" + txtUser.Text + "' and Pass='" + txtPass.Text + "'", conn);

            cmd.Parameters.Add("@Users", SqlDbType.VarChar, 20).Value = login;


            SqlDataReader dr=cmd.ExecuteReader();
            if(dr.Read())
            {
                new Login().Show();
            }
            else
            {
                 lblFail.Text="Invalid username or password";
           }





        }
4

5 に答える 5

2

クエリに値を直接渡しています。Sqlインジェクションを引き起こします。したがって、これを回避するには Sql パラメータを使用する必要があります。ここにあなたのためのアイデアがあります

SqlCommand cmd = new SqlCommand("Select Users,Pass from logintable where Users=@user and Pass=@password", conn);
cmd.Parameters.AddWithValue("@user", txtUserName.Text);
cmd.Parameters.AddWithValue("@password", txtPassword.Text);
reader = cmd.ExecuteReader();
于 2013-04-17T00:11:01.770 に答える
1

以下での文字列連結の使用に注意してください。

"Select Users,Pass from logintable where Users='" + txtUser.Text + "' and Pass='" + txtPass.Text + "'"

これが、コードがインジェクションに対して脆弱になる原因です。パラメータのプレースホルダが必要です:

"Select Users, Pass from logintable where Users=@Users and Pass=@Pass", conn);

パラメータを適切に使用する方法の完全な例は、ここにあります。

于 2013-04-17T00:10:02.800 に答える
0

いいえ、これは完全に間違っています。文字列連結を使用しているため、txtUser.Textandを介して引き続き注入できます。txtPass.Text

.Textクエリでこれら 2 つの値にパラメーターを使用し、実行前に 2 つのプロパティをクエリにバインドする必要があります。

        SqlCommand cmd = new SqlCommand("Select Users,Pass from logintable where Users=@username and Pass=@password", conn);
        cmd.Parameters.AddWithValue("@username", txtUser.Text);
        cmd.Parameters.AddWithValue("@password", txtPass.Text);

もちろん、このようにパスワードを平文で直接保存するべきではありません。適切なパスワード保管方法を検討する必要があります。

于 2013-04-17T00:10:47.750 に答える
0

オブジェクトを使用してCommandいますが、その目的を無効にする値をパラメータ化していませんAddWithValue()。コマンド オブジェクトでメソッドを使用して、そのパラメータを定義できます。

string query = "Select Users,Pass from logintable where Users=@user and Pass=@pass";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("@user", txtUser.Text);
cmd.Parameters.AddWithValue("@pass", txtPass.Text);

さらに、オブジェクトを使用するのではなくExecuteScalar()、オブジェクトから使用して、結果の単一の値を取得できます。CommandDataReader

次のコード スニペットを試してください。

string connStr = "connection string here";
string sqlStatement = @"SELECT COUNT(*) TotalCount
                        FROM logintable 
                        WHERE Users=@user and Pass=@pass";
using (SqlConnection conn = new SqlConnection(connStr))
{
    using(SqlCommand comm = new SqlCommand())
    {
        comm.Connection = conn;
        comm.CommandText = sqlStatement;
        comm.CommandType = CommandType.Text;

        comm.Parameters.AddWithValue("@user", txtUser.Text);
        comm.Parameters.AddWithValue("@pass", txtPass.Text);

        try
        {
            conn.Open();
            int _result = Convert.ToInt32(comm.ExecuteScalar());
            if (_result > 0)
            {
                new Login().Show();
            }
        }
        catch(SqlException e)
        {
            // do something with the exception
            // do not hide it
            // e.Message.ToString()
        }
    }
}

適切なコーディングのために

  • using適切なオブジェクトの破棄には useステートメント
  • ブロックを使用try-catchしてオブジェクトを適切に処理する
于 2013-04-17T00:11:31.037 に答える
0

文字列の連結を使用して SQL ステートメントを作成しないでください。常にパラメーター化されたクエリを使用してください。このコードを試してください:

SqlCommand cmd = new SqlCommand("Select Users, Pass from logintable where Users= @Users  AND Pass=@Pass", conn);
cmd.Parameters.Add("@Users", SqlDbType.VarChar, 20);
cmd.Parameters.Add("@Pass", SqlDbType.VarChar, 20);
cmd.Parameters["@Users"].Value = login;
cmd.Parameters["@Pass"].Value = pass;

conn.Open();

SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read()) 
{
   new Login().show();
}
else
{
   lblFail.Text = "Invalid username and password";
}
reader.Close();
reader.Dispose();

conn.Close();
conn.Dispose();

お役に立てれば。上記のコードを try-catch ブロックで使用し、finally ブロックで Close/Dispose 呼び出しを使用する必要があります。

于 2013-04-17T00:18:07.997 に答える