私は知っています SQLインジェクションはかなり危険です 。今私のC#コードでは、パラメータ化されたクエリを SqlCommand
class で構成しています。
SqlCommand command = ...;
command.CommandText = "SELECT * FROM Jobs WHERE JobId = @JobId;";
command.Parameters.Add("@JobId", SqlDbType.UniqueIdentifier ).Value = actualGuid;
command.ExecuteNonQuery();
これにより、コードは自動的にSQLインジェクションの影響を受けなくなりますか?何か特別なことをする必要がありますか?
パラメータ化されたクエリの特定の、おそらく標準的な例については、そうです、それで十分です。
しかし、人々は時々このようなコードを書きます
cmd.CommandText = string.Format("SELECT * FROM {0} WHERE col = @col;", tableName);
cmd.Parameters.Add("@col", ...);
テーブル名自体をパラメーターとして渡す方法がないため、誤った方向に進んでいるかどうかにかかわらず、やりたいという欲求が存在することがあります。その場合、tableNameが(入力から派生しない静的/定数値のセットからのみ読み取られる場合を除いて)実際にSQLインジェクションを許可していることは見過ごされがちです。
このMSDN記事 に関する注記によると、「特殊な入力文字は、動的SQLでのみ脅威をもたらし、パラメーター化されたSQLを使用する場合は脅威になりません。」
したがって、SQLインジェクションに対して安全であると思います。 URLでID値などの識別子を使用すると、論理的なリスクが発生する可能性がありますが、これは別の話です。
SQLインジェクションは、主に動的SQLの実行に依存しています。つまり、SQLとユーザーが入力した値を連結して作成されたSQLステートメントです。
SQLインジェクションを完全に回避するには、
SQLインジェクション攻撃から身を守ることはそれほど難しくありません。 SQLインジェクション攻撃の影響を受けないアプリケーションは、すべてのユーザー入力を検証およびサニタイズし、動的SQLを使用せず、特権の少ないアカウントを使用して実行し、シークレットをハッシュまたは暗号化し、ハッカーに有用な情報をほとんどまたはまったく明らかにしないエラーメッセージを表示します。予防への多層的なアプローチに従うことにより、1つの防御が回避された場合でも、保護されることが保証されます。
SqlCommandを使用することは非常に良い習慣であり、SQL文字列をどこにも連結しない限り(呼び出すストアドプロシージャ内を含む-つまり、動的SQLを回避する)、SQLインジェクション攻撃の影響を受けません。