コードでパラメーター化された 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 つあります。第一に、これは石器時代から行われてきた方法であり、第二に、データベースで実行される exact クエリが表示されるため、SQL ステートメントのデバッグが容易になります。
それで。私の質問は、SQL インジェクション攻撃を回避するために SafeDBString 関数を使用するだけで本当に十分かどうかです。この安全対策を破るコードの例を見つけようとしていますが、その例は見つかりません。
これを打破できる人はいますか?どのようにしますか?
編集: これまでの返信を要約するには:
- Sql Server 2005 または 2008 で SafeDBString を回避する方法はまだ見つかっていません。それはいいと思いますか?
- いくつかの返信で、パラメーター化されたクエリを使用するとパフォーマンスが向上することが指摘されました。その理由は、クエリ プランを再利用できるからです。
- また、パラメーター化されたクエリを使用すると、コードが読みやすくなり、保守が容易になることにも同意します。
- さらに、さまざまなバージョンの SafeDBString、文字列から数値への変換、および文字列から日付への変換を使用するよりも、常にパラメーターを使用する方が簡単です。
- パラメータを使用すると、自動型変換が得られます。これは、日付や 10 進数を扱う場合に特に便利です。
- 最後に: JulianR が書いたように、セキュリティを自分でやろうとしないでください。データベース ベンダーは、セキュリティに多くの時間とお金を費やしています。私たちがより良くできる方法はなく、彼らの仕事をやろうとする理由もありません.
そのため、SafeDBString 関数の単純なセキュリティを破ることはできませんでしたが、他にも多くの良い議論を得ました。ありがとう!