2012-11-21 8 views
20

SQL Serverデータベースを持つASP.NET Webアプリケーションを使用している場合、SQLインジェクション攻撃が行われる場合、SqlCommandクラスのインスタンスを通過すると想定するのは安全ですか?SqlCommand以外でSQLインジェクション攻撃を実行できますか?

背景:

私はいくつかのSQLインジェクションの脆弱性があり、むしろ大規模なWebアプリケーションを継承した状況にしています。 SQLインジェクションの脆弱性を発見する安全な方法は、すべてのファイルをSqlCommandのインスタンスで検索し、それらがパラメータ化されたクエリであるかどうかを確認することでしょうか?これは確かな計画ですか?

答えて

20

私は特にSqlCommandオブジェクトのためだけを見ていないだろう - コードがたDbCommandかのIDbCommandを使用することができます。それは、EF、L2S、またはNHibernateのようなORMでラップすることができます(すべては、あるレベルの生のアクセスを提供します)。 "dapper"やsimple.dataのようなものを使うことができます。またはDataTable/DataAdapterレガシーOLEDBまたはADODBアクセスを使用するコードを使用している可能性があります。 Heck、あなたが知っている限り、あなた自身の低レベルのTDS APIを書いている可能性があります。

したがって、データアクセスコードのチェックには多くの形があります。あなたの部署のアプローチが「SqlCommandを直接使用する」場合、それは事柄を変更します。

また、SQL注入は.NETに限定されません。たとえば、をパラメータ化しても、生のコマンドテキストまたはストアドプロシージャでSQLインジェクションのリスクを作成できます。 EXECを介して起動される動的SQLを作成します。 sp_executesqlがそれを助けることに注意してください。

+0

あなたが他の誰かのプロジェクトを話しているなら、最後のビットは非常に重要です。 sprocsがある場合は、それらを徹底的に監査したい。データがすでにdbに入っているからといって、SQLコマンドに連結するのは安全ではありません。 – Wedge

+0

すばらしい答え!最後の質問 - インジェクション攻撃がSQL Serverレベルで行われる場合、EXECを使用して実行する必要がありますか? –

8

また使用SqlCommandが含まれているものを探す必要があります。これらには、とりわけSqlDataAdapterが含まれます。

+0

また、パラメーターをパラメーターとして設定する代わりに、パラメーターをクエリ文字列に連結する用途を具体的に見てください。渡された文字列を単に実行する関数が1つしかない場合は、それを古いものにマークし、そのエラーをリファクタリングして、パラメータのコレクションを受け入れるオーバーロードを使用します。 – KeithS

+0

文字列連結を使用するコードを扱う際には、ReSharperを使用して連結をString.Formatの呼び出しにする有用な第一歩を見つけました。次に、フォーマット文字列を定数にリファクタリングするか、String.Formatsを名前付きのメソッドにリファクタリングします。重複を見つけて、文字列を作成するメソッドの代わりにSqlCommandを作成するメソッドにリファクタリングする方がはるかに簡単になります。 –

+0

ヘルパーライブラリが存在する可能性があります。 「データアクセスアプリケーションブロック」または古いSqlHelperにより、注入の脆弱性が容易になります。 – Tass

7

パラメータ化されたクエリライブラリを使用しているという理由だけで、正しく使用されているわけではありません。監査コードの間、私はパラメータ化されたquiresが使用されているケースを見てきましたが、クエリのいくつかの部分はまだ文字列連結を使用して構築されています。より具体的には、クエリのテーブル名と制限/順序部分はよくある間違いです。

静的解析に完全に設定されている場合は、アプリケーション内のすべてのクエリに対してgrepを実行し、それぞれを正しく構築することをお勧めします。はい、これには長い時間がかかります。休憩を取り、メモを取って押してください。あなたがSQLインジェクションを見つけると、それは報われるでしょう!

10

データベーススキーマによっては、ストアドプロキシでの攻撃をチェックする必要があります(ストアドプロシージャを使用していると仮定して)。私は人々が彼らのコードにparamterisedストアドプロシージャを使用して見てきましたが、procの中で、彼らはただ照会するEXECを使用します。

CREATE PROC Dummy 
(
    @Str VARCHAR(50) 
) 
AS 
EXEC ('SELECT * FROM Table Where Column = ''' + @Str + '''') 
関連する問題