ASP.NET アプリケーションで SQL インジェクションに対して脆弱にならないようにする必要があります。どうすればこれを達成できますか?
16 に答える
あなたの質問は非常に一般的ですが、いくつかのルールが常に適用されます。
- パラメーター化されたクエリ (
SqlCommand
withSqlParameter
) を使用し、ユーザー入力をパラメーターに入れます。 - チェックされていないユーザー入力から SQL 文字列を作成しないでください。
- あらゆる種類の不正についてユーザー入力をチェックできるサニタイズ ルーチンを作成できると思い込まないでください。エッジケースは簡単に忘れられます。数値入力をチェックするのは簡単で、安全を確保するのに十分かもしれませんが、文字列入力の場合はパラメーターを使用するだけです。
- 第 2 レベルの脆弱性をチェックします。値がユーザー入力で構成されている場合は、SQL テーブルの値から SQL クエリ文字列を作成しないでください。
- ストアド プロシージャを使用して、データベース操作をカプセル化します。
プリペアド ステートメントを使用します (「製品のノードを追加するには」セクションのプリペアド ステートメントを使用する ASP.NET チュートリアルへのリンク)。それだけです。
それか、 Linq to SQLやNHibernateのような ORM を使用すると、内部的に準備済みステートメントが使用されます。
パラメータを使用してください!それは本当に簡単です:-)
次のようにクエリを作成します (C# を使用する MS Sql サーバーの場合)。
SqlCommand getPersons = new SqlCommand("SELECT * FROM Table WHERE Name = @Name", conn);
ここで、@Name は SQL インジェクションを回避するパラメーターであり、conn は SqlConnection オブジェクトです。次に、パラメーター値を追加するには、次のようにします。
getPersons.Parameters.AddWithValue("@Name", theName);
ここで theName は、検索する名前を含む変数です。
これで、そのクエリで SQL インジェクションを実行することは不可能になるはずです。
これは単純なので、パラメーターを使用しない理由はありません。
ユーザー入力を信頼しない - 検証コントロール、正規表現、コードなどを使用して、すべてのテキスト ボックス エントリを検証します。
動的 SQL を使用しない- パラメータ化された SQL またはストアド プロシージャを使用する
管理者レベルのアカウントを使用してデータベースに接続しない- データベースへの接続には、アクセスが制限されたアカウントを使用してください
シークレットをプレーン テキストで保存しない- パスワードやその他の機密データを暗号化またはハッシュします。接続文字列も暗号化する必要があります
例外は最小限の情報を漏らす必要があります- エラー メッセージであまり多くの情報を漏らさないでください。customErrors を使用して、未処理のエラーが発生した場合に最小限の情報を表示します。デバッグを false に設定
SQL インジェクションは、データベースへのクエリがリアルタイムで構築されているために発生します。次に例を示します。
SELECT * From Table1 WHERE " + UserInput
UserInput
悪意があり、意図しない他のステートメントが含まれている可能性があります。
これを回避するには、クエリを連結しないようにする必要があります。
これは、パラメータ化されたクエリを使用して実現できDBCommand
ます。特定の DB フレーバーのオブジェクトを確認してください。
Scott Guthrieは、これについて少し前にまともな記事を投稿しました。その中で、彼は身を守るための 5 つの提案を提供しています。
タイプ セーフなパラメーター エンコーディング メカニズムを使用せずに、動的 SQL ステートメントを作成しないでください。 [...]
アプリケーションを本番環境に置く前に、常にセキュリティ レビューを実施し、更新を行うたびにすべてのコードをレビューするための正式なセキュリティ プロセスを確立します。 [...]
データベース内に機密データを平文で保存しないでください。 [...]
SQL インジェクション攻撃に対してデータ アクセス レイヤーとアプリケーションを具体的に検証する自動化ユニット テストを作成するようにしてください。 [...]
データベースをロックダウンして、アクセスする Web アプリケーションに、機能するために必要な最小限のアクセス許可セットのみを付与します。 [...]
彼は、なぜこれらが重要なのかを適切に説明し、他のいくつかのリソースへのリンクも提供しています...
パラメーター化されたクエリやストアド プロシージャを使用し、SQL パラメーターを介してパラメーターを解析します。文字列を連結して SQL コードを生成しないでください。SQL インジェクションの防止はセキュリティのほんの一部にすぎないため、SQL インジェクションと安全なコードの記述についても読んでください。他にもたくさんあります (XSS - クロス サイト スクリプティングなど)。ハッカーがサイト/アプリケーションを侵害したい場合、彼は SQL インジェクション以外のものを探します。
ユーザー入力は絶対に信頼せず、常に検証し、SQL パラメータを使用してください。SQL インジェクションを防ぐのに十分な根拠となるはずです。
常にパラメーター化されたクエリのみを使用してください。
うまくいけば、これは役に立ちます:
http://www.codersbarn.com/post/2008/11/01/ASPNET-Data-Input-Validation.aspx
簡単な答えは、パラメーター化されたクエリを使用することです。
アンソニー :-) www.codersbarn.com
他の人が言ったように、ユーザー入力を連結して動的SQLステートメントを作成しないでください。動的 SQL を使用する場合は、常にパラメーター化された SQL を使用してください。ただし、ストアド プロシージャ内に動的 SQL を作成する場合にも、この規則が適用されることを指摘しておきます。この事実は、人々が見落としがちなことです。彼らは、「ストアド プロシージャを使用している」ため、安全だと考えています。
本『Building Secure ASP.NET Applications』ガイドラインには、このトピックに関するセクションがあります。
Microsoft.Security.Application.AntiXss.UrlEncode を使用して XSS Secured UrlEncode を使用すると、SQL インジェクションは機能しません。または、ASP.NET – JSON – シリアライゼーションとデシリアライゼーションを使用できます
また、Macfee Fre Tool の SiteDigger を使用してアプリケーションをテストします。
ここからさらにいくつか
.NET セキュリティ ツールキット v1.0 .NETMon v1.0 Validator.NET v1.0
SQL インジェクションとは何かを正確に理解してから、それに対して脆弱な内容を書かないでください。
ストアド プロシージャを使用して、データの入力を検証してください。INSERT INTO ... のような直接的な SQL は使用しないでください。