0

私は次の認証方法を持っています:

protected void Button1_Click(object sender, EventArgs e)
        {            
            string s;
            s = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
            SqlConnection con = new SqlConnection(s);
            con.Open();
            string sqlCmd;
            sqlCmd = "SELECT Username, UserPassword FROM Benutzer WHERE Username = @Username AND UserPassword =@Password";
            SqlCommand cmd = new SqlCommand(sqlCmd, con);
            String username = tbUsername.Text.Replace("'", "''");
            String password = tbPassword.Text.Replace("'", "''");
            cmd.Parameters.AddWithValue("Username", username);
            cmd.Parameters.AddWithValue("Password", password);
            string CurrentName;
            CurrentName = (string)cmd.ExecuteScalar();
            if (CurrentName != null)
            {
                Session["UserAuthentication"] = cmd.Parameters[0].ToString();
                Session.Timeout = 1;
                Response.Redirect("Default.aspx");
            }
            else
            {
                lblStatus.ForeColor = System.Drawing.Color.Red;
                lblStatus.Text = "Benuztername/Password ungültig!";
            }
        }

これはSQLインジェクションを防ぐのに十分ですか? 私は、次のようにユーザー名とパスワードだけをコマンドに直接入力していました。

sqlCmd = "SELECT Username, UserPassword FROM Benutzer WHERE Username ='" + username + "' AND UserPassword ='" + pwd + "'";

username と pwd は、ユーザー名とパスワードのテキストボックスの内容が格納されている文字列変数のみです...

編集:

わかりました私は今このように見える私のコードを編集しました:

protected void Button1_Click(object sender, EventArgs e)
        {
            SqlConnection objcon = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString());
            SqlDataAdapter objda = new SqlDataAdapter("[MembershipPruefen]", objcon);
            objda.SelectCommand.CommandType = CommandType.StoredProcedure;
            objda.SelectCommand.Parameters.Add("@Username", SqlDbType.VarChar).Value = tbUsername.Text;
            objda.SelectCommand.Parameters.Add("@UserPassword", SqlDbType.VarChar).Value = tbPassword.Text;
            objcon.Open();
            string CurrentName;
            CurrentName = (string)objda.SelectCommand.ExecuteScalar();
            if (CurrentName != null)
            {
                Session["UserAuthentication"] = tbUsername.Text;
                Session.Timeout = 1;
                Response.Redirect("Default.aspx");
            }
            else
            {
                lblStatus.ForeColor = System.Drawing.Color.Red;
                lblStatus.Text = "Benuztername/Password ungültig!";
            }
            objcon.Close();            
        }

これは私のストアドプロシージャです:

CREATE PROCEDURE MembershipPruefen (@Username VARCHAR(50), @UserPassword VARCHAR(50))  
AS 

SELECT Username, UserPassword FROM Benutzer WHERE Username LIKE @Username AND UserPassword LIKE @UserPassword; 

これで十分ですか?私の Web アプリは sql 感染に対して安全でしょうか? それともまだ何かすべきことがありますか?

4

4 に答える 4

2

データベースに接続するための専用のSQLサーバーユーザーを作成します(今、「sa」に接続していると思いますか?)。

これは、まったく権限のない新しいユーザーをデータベースに追加することを意味します。アプリを最初に実行すると、予想どおり、読み取り権限がないことを示す SQL 例外が発生します。新しく作成されたユーザーなどの「Benutzer」テーブルに SELECT 権限を付与します。

これを行うと、接続が侵害された場合でも、攻撃者はシステム ストアド プロシージャなどを実行できなくなります。

もう 1 つ: パスワードをハッシュ化することをお勧めします。これにより、パスワードが実際のテキストで読み取られることはありません。これは大規模な記事であり、あまり時間がないことがわかりましたが、ハッシュ化されたパスワードを実装することを強くお勧めします。 http://crackstation.net/hashing-security.htm

LIKE編集:ストアド プロシージャにa が表示されます=。ユーザーは正確なパスワードを入力する必要があります。

そして、SQL ステートメントからストアド プロシージャに変更したことがわかります。前のテキストでは、テーブルに対する SELECT 権限をストアド プロシージャに対する EXECUTE 権限に変更しています。

于 2013-03-12T15:12:35.540 に答える
2

ストアド プロシージャを使用し、値がデータベースに存在することを示す値 (つまり、行数) のみを返すか、セッション データなどにユーザー名を使用する必要がある場合は、ユーザー名を返すだけです。

これにより、ユーザーに公開される DB データがさらに少なくなります :)

ストアド プロシージャに関する情報: http://support.microsoft.com/kb/306574

于 2013-03-12T14:15:54.520 に答える
2

パラメーター化されたクエリ (SqlParameter を使用した SqlCommand) を使用し、ユーザー入力をパラメーターに入れます。チェックされていないユーザー入力から SQL 文字列を作成しないでください。あらゆる種類の不正についてユーザー入力をチェックできるサニタイズ ルーチンを作成できると思い込まないでください。エッジケースは簡単に忘れられます。数値入力をチェックするのは簡単で、安全を確保するのに十分かもしれませんが、文字列入力の場合はパラメーターを使用するだけです。第 2 レベルの脆弱性をチェックします。値がユーザー入力で構成されている場合は、SQL テーブルの値から SQL クエリ文字列を作成しないでください。ストアド プロシージャを使用して、データベース操作をカプセル化します。

または、Linq to SQL や NHibernate のように、ORM を使用して形成される準備済みステートメントを使用します。内部的に準備済みステートメントを使用します。

于 2013-03-12T14:18:39.537 に答える
1

準備済みステートメントを使用します。

SqlCommand.Prepare

MSDN

于 2013-03-12T14:12:55.477 に答える