ホームページ > 記事 > WeChat アプレット > PHPでSQLインジェクションを防ぐ方法を詳しく解説
この記事では主にPHPにおけるSQLインジェクションを防ぐ方法を紹介します。非常に優れた参考値です。以下のエディターで見てみましょう
1. SQL インジェクション攻撃とは何ですか?
いわゆる SQL インジェクション攻撃とは、攻撃者が入力フィールドまたは入力フィールドに SQL コマンドを挿入することを意味します。 Web フォームのページ 要求されたクエリ文字列により、サーバーが悪意のある 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 login = '' or '1'='1' AND passwd = '' or '1'='1'.
⑸ サーバーはクエリまたはストアド プロシージャを実行して ID を結合しますユーザーが入力した情報と、サーバー情報に保存された ID を比較します。
⑹ SQL コマンドは実際にはインジェクション攻撃によって変更されているため、ユーザーの身元を真に検証することができず、システムは攻撃者を誤って承認します。
アプリケーションがフォームに入力された内容を本人確認クエリに直接使用することを攻撃者が知っている場合、攻撃者は特別な SQL 文字列を入力してクエリを改ざんし、元の機能を変更し、システムを騙してアクセス許可を付与しようとします。 。
システム環境に応じて、攻撃者が引き起こす可能性のある被害も異なります。これは主に、データベースにアクセスするためのアプリケーションのセキュリティ権限によって決まります。ユーザーのアカウントに管理者またはその他の比較的高度な権限がある場合、攻撃者は、データの追加、削除、更新、さらにはテーブルの直接削除など、データベース テーブルに対してさまざまな操作を実行する可能性があります。
2. どうやって防ぐのですか?
幸いなことに、フォームに入力されたコンテンツを使用する前にすべての入力コンテンツがフィルターされている限り、ASP.NET アプリケーションへの侵入を防ぐことは特に難しくありません。 SQL コマンドを構築する 1 つのセッションだけで十分です。入力のフィルタリングはさまざまな方法で実行できます。
(1) SQL クエリが動的に構築される状況では、次のテクノロジーを使用できます:
最初: 一重引用符を置換します。つまり、単独で表示されるすべての一重引用符を 2 つの一重引用符に変更して、攻撃者が SQL コマンドを変更できないようにします。 。 意味。前の例をもう一度見てみると、「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 コマンドの実行に使用されるのを防ぎます。
(2) ストアド プロシージャを使用してすべてのクエリを実行します。 SQL パラメータの受け渡し方法により、攻撃者が一重引用符やハイフンを使用して攻撃を実行することを防ぎます。さらに、特定のストアド プロシージャの実行のみを許可するようにデータベースのアクセス許可を制限することもできるため、インジェクション攻撃が発生しにくくなるように、すべてのユーザー入力が呼び出されたストアド プロシージャのセキュリティ コンテキストに準拠する必要があります。
(3) フォームまたはクエリ文字列の入力の長さを制限します。ユーザーのログイン名が最大 10 文字しかない場合は、フォームに 10 文字を超える文字を入力しないでください。これにより、攻撃者が SQL コマンドに有害なコードを挿入することが大幅に困難になります。
(4) ユーザー入力の合法性をチェックし、入力内容に合法的なデータのみが含まれていることを確認します。データ検査はクライアント側とサーバー側の両方で実行する必要があります。サーバー側の検証は、クライアント側の検証メカニズムの脆弱なセキュリティを補うために実行されます。
クライアント側では、攻撃者が Web ページのソース コードを取得し、合法性を検証するスクリプトを変更し (またはスクリプトを直接削除し)、変更されたフォームを通じて違法なコンテンツをサーバーに送信することが完全に可能です。 。したがって、検証操作が実際に実行されたことを確認する唯一の方法は、サーバー側でも検証を実行することです。検証用のクライアント側スクリプトを自動的に生成できる RegularExpressionValidator など、多くの組み込み検証オブジェクトを使用できます。もちろん、サーバー側のメソッド呼び出しを挿入することもできます。既製の検証オブジェクトが見つからない場合は、CustomValidator を使用して自分で作成できます。
(5) ユーザーのログイン名、パスワードなどのデータを暗号化して保存します。ユーザーが入力したデータを暗号化し、データベースに保存されているデータと比較することは、ユーザーが入力したデータを「殺菌」することと同等であり、ユーザーが入力したデータはデータベースにとって特別な意味を持たなくなります。攻撃者が SQL コマンドを挿入するのを防ぎます。 System.Web.Security.FormsAuthentication クラスには HashPasswordForStoringInConfigFile があり、入力データのサニタイズに非常に適しています。
(6) データを抽出したクエリによって返されたレコードの数を確認します。プログラムで返されるレコードが 1 つだけであるにもかかわらず、実際に返されるレコードが複数行である場合、エラーとして扱われます。
(7) プリペアドステートメントを使用する
SQL インジェクションを防ぐための PHP の方法の詳細な説明については、PHP 中国語 Web サイトの関連記事に注目してください。