1

ASP.netアプリケーションにパラメーター化SQLクエリを追加するのは興味深いことです。SQLインジェクションの回避に関するいくつかの良い記事を見てきました。

string sql = string.Format("INSERT INTO [UserData] (Username, Password, Role, Membership, DateOfReg) VALUES (@Username, @Password, @Role, @Membership, @DateOfReg)");
        SqlCommand cmd = new SqlCommand(sql, conn);
        try
        {
        cmd.Parameters.AddWithValue("Username", usernameTB.Text);
        cmd.Parameters.AddWithValue("Password", passwordTB.Text);
        cmd.Parameters.AddWithValue("Role", roleTB.Text);
        cmd.Parameters.AddWithValue("Membership", membershipTB.Text);
        cmd.Parameters.AddWithValue("DateOfReg", dorTB.Text);

        conn.Open();
        cmd.ExecuteNonQuery();
        conn.Close();

リファレンスを見つける

ただし、この方法は、DB接続を再利用しているため、別のクラスに結合しているため、役に立ちません。

public class DBconnection{     
    public int insertQuery(String query) {



            int affectedRowCount = 0;
            SqlConnection conn = null;
            try{

                conn = new SqlConnection("Server=localhost;Database=master;UID=sa;PWD=sa;");
                SqlCommand cmd = new SqlCommand( query, conn );
                cmd.CommandType = CommandType.Text;

                conn.Open(  );
                affectedRowCount = cmd.ExecuteNonQuery(  );
                conn.Close(  );         

            } catch ( Exception e ){

                       String error = e.Message;

            }

            return affectedRowCount;
    }
}

したがって、以下のコード部分のみを使用して、上記のクラスを呼び出し、DBに値を挿入します。

 String SQLQuery1 = insert into Article values('" + Txtname.Text + "','" + TxtNo.Text + "','" + Txtdescription.Text + "' ,0)");
DBconnection dbConn = new DBconnection();
        SqlDataReader Dr = dbConn.insertQuery(SQLQuery1);

SQLインジェクションを回避するためにParameterizesqlStringを使用するのを手伝ってください。テキストボックス入力を使用せずに@name、@ No、および@descriptionを使用するには。

4

3 に答える 3

1

これを行うのは完全に合理的ですが、パラメーターを取得するためにクラスにコールバック (ラムダ/デリゲート) を出させます。これは、さまざまなオーバーロードされたインスタンス メソッドによって呼び出されるクラスの静的メソッドです。

private static int SqlExec(string ConnectionString, string StoredProcName, Action<SqlCommand> AddParameters, Action<SqlCommand> PostExec)
        {
            int ret;
            using (var cn = new SqlConnection(ConnectionString))
            using (var cmd = new SqlCommand(StoredProcName, cn))
            {
                cn.Open();
                cmd.CommandType = CommandType.StoredProcedure;

                if (AddParameters != null)
                {
                    AddParameters(cmd);
                }

                ret = cmd.ExecuteNonQuery();

                if (PostExec != null)
                {
                    PostExec(cmd);
                }
            }
            return ret;
        }

次に、使用例:

    public void Save()
    {
        Data.Connect().Exec("Project_Update", Cm =>
        {
            Cm.Parameters.AddWithValue("@ProjectID", ID);
            Cm.Parameters.AddWithValue("@PrimaryApplicantID", PrimaryApplicant.IdOrDBNull());
            Cm.Parameters.AddWithValue("@SecondaryApplicantID", SecondaryApplicant.IdOrDBNull());
            Cm.Parameters.AddWithValue("@ProjectName", ProjectName.ToDBValue());
        });
    }

これは、ストアド プロシージャ以外の呼び出しでも可能です。

あなたの場合、次のようになります。

DBconnection.InsertQuery(
    "INSERT INTO [UserData]
        (Username, Password, Role, Membership, DateOfReg)
        VALUES (@Username, @Password, @Role, @Membership, @DateOfReg)"
    ,cmd => {
                cmd.Parameters.AddWithValue("Username", usernameTB.Text);
                cmd.Parameters.AddWithValue("Password", passwordTB.Text);
                cmd.Parameters.AddWithValue("Role", roleTB.Text);
                cmd.Parameters.AddWithValue("Membership", membershipTB.Text);
                cmd.Parameters.AddWithValue("DateOfReg", dorTB.Text);
            }
);

これにより、すべてのデータベースが必要な方法でまとめられ、DBconnection が内部を分離した状態に保つことができます。

于 2012-04-23T01:28:36.103 に答える
1

一般的な InsertQuery() メソッドの代わりに、特定の InsertQuery メソッドを作成するのはどうですか?

例えば:

public void AddNewUser(User u)
{
   var query = "insert Users (name, password) values (@0, @1)";
   SqlCommand cmd = new SqlCommand(query, conn);
        try
        {
        cmd.Parameters.AddWithValue("@0", u.UserName);
        cmd.Parameters.AddWithValue("@1", u.Password);
        }
}

これには、呼び出し元のクラスがクエリの作成方法などを知る必要があるのとは対照的に、すべての SQL ロジックがこの他のクラスにあるという利点があります。

また、メソッド呼び出しとして or が表示されるため、コードが読みやすくなり、AddUserそのUpdateUser時点ChangePasswordで SQL を読んでプログラムで何が起こっているのかを推測する必要がなくなります。

ただし、このようなことを行う場合は、いくつかの MicroORM を確認する必要があります。私の個人的なお気に入りはPetaPoco (またはNuGet バージョン)です。

PetaPoco や、Massive や Dapper などの他のユーザーは、次のようなことができます。

database.Insert(u);

u は、DB のテーブルにマップされるユーザー オブジェクトです。ADO.NET を使用し、SQL パラメータを確実に使用します。

于 2012-04-22T16:43:36.857 に答える
0

すべてを自動的にパラメータ化するLINQ to SQL を使用することをお勧めします。

Q. LINQ to SQL は SQL インジェクション攻撃からどのように保護されていますか?

A. SQL インジェクションは、ユーザー入力を連結して形成される従来の SQL クエリにとって重大なリスクでした。LINQ to SQL では、クエリで SqlParameter を使用することにより、このようなインジェクションを回避します。ユーザー入力はパラメーター値に変換されます。このアプローチにより、悪意のあるコマンドが顧客の入力から使用されるのを防ぎます。

を使用して簡単な方法で SQL データベースから挿入、更新、および削除できDataContextます (プロジェクトを右クリックして新しい項目を追加し、LINQ to SQL Classesテンプレートを追加してから、サーバー エクスプローラーを使用してオブジェクトを追加します)。

私はしばらくこれを扱っていませんでしたが、コードは次のようになると思います。

UserData user = new UserData();

user.Username = ...;
user.Password = ...;
user.Role = ...;
user.Membership = ...;
user.DateOfReg = ...;

db.UserDatas.InsertOnSubmit(user);
db.SubmitChanges();

SubmitChanges を呼び出すと、LINQ to SQL は、変更をデータベースに送信するために必要な SQL コマンドを自動的に生成して実行します。

編集1:

追加のメモとして、データベースから既存のアイテムを取得するには、次のようにします。

var user = (from i in db.UserDatas
            where i.UserName == "devan"
            select i).Single();

ああ、ログイン情報でデータベースに関する質問に答えるときの私の標準的なポリシーと同様に、神の愛とすべての聖なるもののために、ユーザーのパスワードをソルトしてハッシュするようにあなたに懇願しなければなりません.

于 2012-04-22T16:47:51.283 に答える