ここで、コードでパラメーター化されたSQLクエリを使用することについて、別の議論が行われています。議論には2つの側面があります。私と、SQLインジェクションから常に保護するためにパラメーターを使用する必要があると言う他の人と、それが必要だと思わない他の人です。代わりに、SQLインジェクションを回避するために、すべての文字列で単一のアポストロフィを2つのアポストロフィに置き換えたいと考えています。私たちのデータベースはすべてSql Server 2005または2008を実行しており、コードベースは.NET Framework 2.0で実行されています。
C#で簡単な例を挙げましょう。
私はこれを使って欲しい:
string sql = "SELECT * FROM Users WHERE Name=@name";
SqlCommand getUser = new SqlCommand(sql, connection);
getUser.Parameters.AddWithValue("@name", userName);
//... blabla - do something here, this is safe
他の人がこれをしたい間:
string sql = "SELECT * FROM Users WHERE Name=" + SafeDBString(name);
SqlCommand getUser = new SqlCommand(sql, connection);
//... blabla - are we safe now?
SafeDBString関数は次のように定義されています。
string SafeDBString(string inputValue)
{
return "'" + inputValue.Replace("'", "''") + "'";
}
これで、クエリのすべての文字列値でSafeDBStringを使用する限り、安全であるはずです。正しい?
SafeDBString関数を使用する理由は2つあります。1つ目は、石器時代からのやり方です。2つ目は、データベースで実行されている正確なクエリが表示されるため、SQLステートメントのデバッグが簡単です。
それで。私の質問は、SQLインジェクション攻撃を回避するためにSafeDBString関数を使用するだけで十分かどうかです。私はこの安全対策を破るコードの例を見つけようとしましたが、その例は見つかりません。
これを壊すことができる誰かがいますか?どうしますか
編集: これまでの返信を要約するには:
- Sql Server 2005または2008でSafeDBStringを回避する方法はまだ見つかっていません。それは良いと思いますか?
- パラメータ化されたクエリを使用するとパフォーマンスが向上することがいくつかの回答で指摘されています。その理由は、クエリプランを再利用できるためです。
- また、パラメーター化されたクエリを使用すると、より読みやすいコードが維持されやすくなることに同意します
- さらに、SafeDBStringのさまざまなバージョン、文字列から数値への変換、文字列から日付への変換を使用するよりも、常にパラメーターを使用する方が簡単です。
- パラメータを使用すると、自動型変換が行われます。これは、日付や10進数を扱うときに特に役立ちます。
- そして最後に:JulianRが書いたように自分でセキュリティを試みようとしないでください。データベースベンダーは、セキュリティに多くの時間とお金を費やしています。私たちがもっと上手にできる方法はなく、私たちが彼らの仕事をしようとする理由はありません。
したがって、SafeDBString関数の単純なセキュリティを破ることができた人はいませんでしたが、私は他の多くの良い議論を得ました。ありがとう!