9

私のアイデアは、MySQL .NET Connector 6.2.2を介してMySQLデータベースと通信するC#(3.5)Winformsアプリを介してInsert / Update/Selectの汎用クラスを作成することです。

例えば:

public void Insert(string strSQL)
{
   if (this.OpenConnection() == true)
   {
       MySqlCommand cmd = new MySqlCommand(strSQL, connection);
       cmd.ExecuteNonQuery();
       this.CloseConnection();
   }
}

次に、プログラムのどこからでも、SQLクエリ文字列を渡すだけで、ユーザー入力の有無にかかわらずクエリを実行できます。

SOを読み回すと、これがSQLインジェクション攻撃につながる可能性があることがわかり始めています(ユーザー入力値の場合)。入力されたstrSQLをスクラブする方法はありますか、それともデータベース関数を実行する必要があるすべてのメソッドで個別のパラメーター化されたクエリを作成する必要がありますか?

UPDATE1:

私の最終的な解決策は次のようになります。

public void Insert(string strSQL,string[,] parameterValue)
{
   if (this.OpenConnection() == true)
   {
       MySqlCommand cmd = new MySqlCommand(strSQL, connection);

       for(int i =0;i< (parameterValue.Length / 2);i++)
       {                        
       cmd.Parameters.AddWithValue(parameterValue[i,0],parameterValue[i,1]);          
       }

       cmd.ExecuteNonQuery();
       this.CloseConnection();
   }}
4

8 に答える 8

12

パラメータ化は非常に簡単です。SQL クエリをスクラブするよりもはるかに簡単で、手動でエスケープするよりも煩雑でエラーが発生しにくくなります。

私は怠け者なので、このチュートリアルページからのコピー/貼り付けを少し編集しました。

// User input here
Console.WriteLine("Enter a continent e.g. 'North America', 'Europe': ");
string userInput = Console.ReadLine();

string sql = "SELECT Name, HeadOfState FROM Country WHERE Continent=@Continent";
MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@Continent", userInput);

using (MySqlDataReader dr = cmd.ExecuteReader())
{
    // etc.
}

そんなに難しくなかったですよね?:)

于 2010-05-05T18:24:02.213 に答える
11

自分自身を安全に保つために、パラメーター化されたクエリを確実に使用する必要があります。

ただし、パラメーター化されたクエリを毎回手動で作成する必要はありません。提供したジェネリック メソッドを変更して、次のコレクションを受け入れることができますMySqlParameters

public void Insert(string strSQL, List<MySqlParameter> params)
{
    if(this.OpenConnection() == true)
    {
        MySqlCommand cmd = new MySqlCommand(strSQL, connection)
        foreach(MySqlParameter param in params)
            cmd.Parameters.Add(param);

        cmd.ExecuteNonQuery();
        this.CloseConnection();
    }
}

また、接続の使用が終了したら、接続のクリーンアップに非常に注意する必要があることにも言及する必要があります(通常はusingブロックで処理されますが、コード例ではそのレベルの詳細はわかりません)。

于 2010-05-05T18:20:35.410 に答える
1

事後にSQLインジェクションを検出することは不可能です(つまり、動的クエリ文字列を作成すると、「実際の」SQLとインジェクションされたSQLを区別することはできません)。

ユーザーが任意のSQLを実行できるようにすることを目的としている場合は、SQLインジェクションについてあまり心配する必要はないように思われます(これがSQLインジェクションの目的であるため)。

于 2010-05-05T18:16:59.963 に答える
1

SQLに使用される生のテキストをスクラブするのはかなり難しいと思います。可能であれば、パラメーター化された操作を使用しようとします。

1つの例外は、関数を公開せず、生のユーザー入力から作成された文字列を渡さなかった場合です。

于 2010-05-05T18:17:02.330 に答える
1

if you use MySqlParameter and do not generate plain string queries you are safe.

于 2010-05-05T18:17:09.607 に答える
1

実際にはこれを行うことはできません.SQLパーサーを書く必要があります.SQLパーサーは控えめに言っても重要でエラーが発生しやすいです.

弾丸をかじって、クエリをパラメータ化します。

于 2010-05-05T18:17:39.710 に答える
1

IDataParameter オブジェクトを利用してクエリをパラメータ化することをお勧めします。

于 2010-05-05T18:18:43.110 に答える
1

はい、パラメーター化されたクエリを作成する必要があります。それ以外の場合は、SQL インジェクションのリスクが発生します

于 2010-05-05T18:25:32.070 に答える