1. SQL インジェクション攻撃とは何ですか?
いわゆる SQL インジェクション攻撃とは、攻撃者が Web フォームの入力フィールドまたはページ リクエストのクエリ文字列に SQL コマンドを挿入し、サーバーを騙して悪意のあるコードを実行させることを意味します。 SQLコマンド。一部のフォームでは、ユーザーが入力した内容が動的 SQL コマンドの構築 (または影響) に直接使用されたり、ストアド プロシージャの入力パラメーターとして使用されたりすることがあります。このようなフォームは SQL インジェクション攻撃に対して特に脆弱です。一般的な SQL インジェクション攻撃プロセスは次のとおりです。
⑴ ASP.NET Web アプリケーションにはログイン ページがあり、ユーザーがアプリケーションにアクセスする権利があるかどうかを制御します。ユーザーは名前とパスワードを入力する必要があります。
⑵ ログインページに入力された内容は、動的SQLコマンドの構築に直接使用されたり、ストアドプロシージャのパラメータとして直接使用されます。以下は、クエリを構築する ASP.NET アプリケーションの例です。
System.Text.StringBuilder query = new System.Text.StringBuilder(
"SELECT * from Users WHERE login = '")
.Append(txtLogin.Text) ).Append ("' AND password='")
.Append(txtPassword.Text).Append("'");
⑶ 攻撃者はユーザー名に「' または '1'='1」を入力し、パスワード入力ボックスの内容はそのようなものです。
⑷ ユーザーが入力したコンテンツがサーバーに送信された後、サーバーは上記の ASP.NET コードを実行してユーザーにクエリを実行する SQL コマンドを構築します。ただし、攻撃者が入力したコンテンツは非常に特殊であるため、最後に実行されます。 SQL コマンドは次のようになります: SELECT * from Users WHERE ログイン = '' または '1'='1' AND パスワード = '' または '1'='1'。
⑸ サーバーはクエリまたはストアドプロセスを実行して、ユーザーが入力したアイデンティティ情報とサーバーに保存されているアイデンティティ情報を比較します。
⑹ SQL コマンドは実際にはインジェクション攻撃によって変更されており、ユーザーの ID を真に認証できないため、システムは攻撃者を誤って承認します。
アプリケーションがフォームに入力された内容を本人確認クエリに直接使用することを攻撃者が知っている場合、攻撃者は特別な SQL 文字列を入力してクエリを改ざんし、元の機能を変更し、システムを騙してアクセス許可を付与させようとします。 。
システム環境が異なり、攻撃者が引き起こす可能性のある被害も異なります。これは主に、データベースにアクセスするためのアプリケーションのセキュリティ権限によって決まります。ユーザーのアカウントに管理者またはその他の比較的高度な権限がある場合、攻撃者は、データの追加、削除、更新、さらにはテーブルの直接削除など、データベース テーブルに対してさまざまな操作を実行する可能性があります。
2. それを防ぐ方法は?
幸いなことに、フォームに入力されたコンテンツを使用する前にすべての入力コンテンツがフィルターされている限り、ASP.NET アプリケーションへの侵入を防ぐことは特に難しくありません。 SQL コマンドを作成するには 1 つのセッションだけで十分です。入力のフィルタリングはさまざまな方法で実行できます。
⑴ SQL クエリが動的に構築される状況では、次の手法を使用できます:
最初: 一重引用符を置換します。つまり、攻撃者が SQL の意味を変更できないように、単独で表示されるすべての一重引用符を 2 つの一重引用符に変更します。コマンド。前の例をもう一度見てみると、「SELECT * from Users WHERE login = ''' or ''1''=''1' AND passwd = ''' or ''1''=''1'」は明らかに取得されます。同じ「SELECT * from Users WHERE login = '' または '1'='1' AND パスワード = '' または '1'='1'」でも結果は異なります。
2 番目: ユーザー入力内のすべてのハイフンを削除して、攻撃者が「SELECT * from Users WHERE login = 'mas' -- AND password =''」などのクエリを作成できないようにします。このようなクエリは後半がコメントアウトされており、は有効ではなくなりました。攻撃者が知っている必要があるのは正当なユーザーのログイン名だけであり、アクセスを成功させるためにユーザーのパスワードを知る必要はありません。
3番目: クエリの実行に使用されるデータベースアカウントの権限を制限します。別のユーザー アカウントを使用して、クエリ、挿入、更新、削除の操作を実行します。異なるアカウントで実行できる操作を分離することで、元々 SELECT コマンドの実行に使用されていた場所が INSERT、UPDATE、または DELETE コマンドの実行に使用されるのを防ぎます。
⑵ ストアドプロシージャを使用してすべてのクエリを実行します。 SQL パラメータの受け渡し方法により、攻撃者が一重引用符やハイフンを使用して攻撃を実行することを防ぎます。さらに、特定のストアド プロシージャの実行のみを許可するようにデータベースのアクセス許可を制限することもできるため、インジェクション攻撃が発生しにくくなるように、すべてのユーザー入力が呼び出されたストアド プロシージャのセキュリティ コンテキストに準拠する必要があります。
⑶ フォームまたはクエリ文字列の入力の長さを制限します。ユーザーのログイン名が最大 10 文字しかない場合は、フォームに 10 文字を超える文字を入力しないでください。これにより、攻撃者が SQL コマンドに有害なコードを挿入することが大幅に困難になります。
⑷ ユーザー入力の合法性をチェックし、入力内容に合法的なデータのみが含まれていることを確認します。データ検査はクライアント側とサーバー側の両方で実行する必要があります。サーバー側の検証は、クライアント側の検証メカニズムの脆弱なセキュリティを補うために実行されます。
クライアント側では、攻撃者が Web ページのソース コードを取得し、合法性を検証するスクリプトを変更し (またはスクリプトを直接削除し)、変更されたフォームを通じて違法なコンテンツをサーバーに送信することが完全に可能です。したがって、検証操作が実際に実行されたことを確認する唯一の方法は、サーバー側でも検証を実行することです。検証用のクライアント側スクリプトを自動的に生成できる RegularExpressionValidator など、多くの組み込み検証オブジェクトを使用できます。もちろん、サーバー側のメソッド呼び出しを挿入することもできます。既製の検証オブジェクトが見つからない場合は、CustomValidator を使用して自分で作成できます。
⑸ ユーザーのログイン名、パスワード、その他のデータを暗号化して保存します。ユーザーが入力したデータを暗号化し、データベースに保存されているデータと比較することは、ユーザーが入力したデータを「殺菌」することと同等であり、ユーザーが入力したデータはデータベースにとって特別な意味を持たなくなります。攻撃者が SQL コマンドを挿入するのを防ぎます。 System.Web.Security.FormsAuthentication クラスには HashPasswordForStoringInConfigFile があり、入力データのサニタイズに非常に適しています。
⑹ データを抽出したクエリによって返されたレコードの数を確認します。プログラムで返されるレコードが 1 つだけであるにもかかわらず、実際に返されるレコードが複数行である場合、エラーとして扱われます。